Tip: It's better to have a real date field in the database and not just Year / Month. That way you can create a date index in addition to the clustered index.
However if you have FullDate
, Year
and Month
you can get the same error message view contains an expression on result of aggregate function or grouping column
.
That error can occur if you do this:
SELECT
[Manufacturer]
,[Date] as FullDate
,DATEPART(year,[Date]) as Year
,DATEPART(month,[Date]) as Month
,COUNT_BIG(*) as Count
,SUM(OrderValue) as TotalOrderValue
FROM [dbo].[TABLE1]
Group By
[Manufacturer]
,[Date]
,DATEPART(year,[Date])
,DATEPART(month,[Date])
While not immediately obvious what's going on I assume this is because it looks at Date
in the grouping columns and finds Date
used in other columns (for the year and month). Clearly though this should logically work and you should be able to group like that.
I found a trick that got it working:
SELECT
[Manufacturer]
,DATEADD(day, 0, [Date]) as FullDate
,DATEPART(year,[Date])as Year
,DATEPART(month,[Date])as Month
,COUNT_BIG(*) as Count
,SUM(OrderValue) as TotalOrderValue
FROM [dbo].[TABLE1]
Group By
[Manufacturer]
,DATEADD(day, 0, [Date])
,DATEPART(year,[Date])
,DATEPART(month,[Date])
This tricked the parser into allowing it, and now I can create a separate index (after the clustered) to search by FullDate.
Bonus: The real reason I stumbled upon this was because I needed ISO_WEEK and ISO_YEAR which are expensive to calculate. Here here's my final full list of grouping clauses I'm using for that:
-- date
DATEADD(day, 0, [Order].OrderDateDt) as OrderDateDt, -- trick! add 0 days to date
-- day / month / year / quarter
DATEPART(day, [Order].OrderDateDt) as OrderDate_day,
DATEPART(month, [Order].OrderDateDt) as OrderDate_month,
DATEPART(year, [Order].OrderDateDt) as OrderDate_year,
DATEPART(quarter, [Order].OrderDateDt) as OrderDate_quarter,
-- iso week
DATEPART(iso_week, [Order].OrderDateDt) as OrderDate_isoweek,
YEAR(DATEADD(day, 26 - DATEPART(iso_week, [Order].OrderDateDt), [Order].OrderDateDt)) as OrderDate_isoyear
Make sure to include all these exactly the same in the SELECT and GROUP BY.