Reputation: 857
I want to group by results of sales by YEAR-MONTH. My current query which does the results looks like :
SELECT Cast(Year(s.datekey) AS VARCHAR(4)) + '-'
+ Cast(Month(s.datekey) AS VARCHAR(2)) AS Mjesec,
e.employeekey,
Sum(s.totalcost) AS SalesAmount
FROM factsales s
INNER JOIN dimstore st
ON s.storekey = st.storekey
INNER JOIN dimemployee e
ON e.employeekey = st.storemanager
WHERE s.datekey BETWEEN '2007-01-01' AND '2007-01-05'
GROUP BY e.employeekey,
Cast(Year(s.datekey) AS VARCHAR(4)) + '-'
+ Cast(Month(s.datekey) AS VARCHAR(2))
ORDER BY employeekey
I am wondering if there are any other better and more elegant way to achieve same results? Perhaps, more friendly format for DateTime in c#?
Upvotes: 0
Views: 490
Reputation: 280252
Much more efficient to strip time by using date math than converting to a string. Also much more efficient to leave the particular string formatting to the end (or better yet, doing it in C# using Format()
).
;WITH c AS
(
SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
),
d AS
(
SELECT m, employeekey, SalesAmount = SUM(totalcost)
FROM c
GROUP BY m, employeekey
)
SELECT
Mjesec = CONVERT(CHAR(7), m, 120),
employeekey,
SalesAmount
FROM d
ORDER BY employeekey;
If you can do the formatting in your app, then you can collapse this to:
;WITH c AS
(
SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
)
SELECT Mjesec = m, employeekey, SalesAmount = SUM(totalcost)
FROM c
GROUP BY m, employeekey
ORDER BY employeekey;
Or even:
SELECT Mjesec = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, s.datekey, 0), 0), e.employeekey
ORDER BY employeekey;
Upvotes: 1
Reputation: 70638
Do:
SELECT CONVERT(CHAR(7),s.DateKey,120) AS Mjesec....
FROM ....
GROUP BY CONVERT(CHAR(7),s.DateKey,120)....
ORDER BY EmployeeKey
Upvotes: 1