February 3, 2009 at 2:50 pm
I have a table that contains daily sales information one row per day. The columns to be used are Location_Code, System_Date and Royalty_Sales. I want a query that returns the highest sales level for each day of the week AND the date that occurred on. I have:
SELECT Location_Code,
MAX(CASE WHEN DATEPART(weekday, System_Date) = 1 THEN Royalty_Sales ELSE 0 END) AS ,
MAX(CASE WHEN DATEPART(weekday, System_Date) = 2 THEN Royalty_Sales ELSE 0 END) AS [M],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 3 THEN Royalty_Sales ELSE 0 END) AS [Tu],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 4 THEN Royalty_Sales ELSE 0 END) AS [W],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 5 THEN Royalty_Sales ELSE 0 END) AS [Th],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 6 THEN Royalty_Sales ELSE 0 END) AS [F],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 7 THEN Royalty_Sales ELSE 0 END) AS [Sa]
FROM Daily_Summary
WHERE System_Date >= @dateLow AND System_Date <= @dateHigh
GROUP BY Location_Code
ORDER BY Location_Code
This works terrific, but for the life of me I can't figure out how to also get the DATE that the MAX for each day occurs on.
Please educate.
Shawn
February 4, 2009 at 9:45 am
Hi Shawn,
I'm not sure how your data is actually stored (i.e. table structures), but you can handle this a couple of ways. One is just to add another CASE statement to your existing query.
Create Table #myTable
(
Location_Code int
, System_Date datetime
, Royalty_Sales int
);
Insert Into #myTable
Select 1, '2009-01-01', 100 Union All
Select 1, '2009-01-02', 100 Union All
Select 1, '2009-01-03', 100 Union All
Select 1, '2009-01-04', 100 Union All
Select 1, '2009-01-05', 100 Union All
Select 1, '2009-01-06', 100 Union All
Select 1, '2009-01-07', 100 Union All
Select 2, '2009-01-01', 100 Union All
Select 2, '2009-01-02', 100 Union All
Select 2, '2009-01-03', 100 Union All
Select 1, '2009-01-08', 200 Union All
Select 1, '2009-01-09', 200;
SELECT Location_Code,
MAX(CASE WHEN DATEPART(weekday, System_Date) = 1 THEN Royalty_Sales ELSE 0 END) AS ,
MAX(CASE WHEN DATEPART(weekday, System_Date) = 1 THEN System_Date ELSE Null END) AS ,
MAX(CASE WHEN DATEPART(weekday, System_Date) = 2 THEN Royalty_Sales ELSE 0 END) AS [M],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 2 THEN System_Date ELSE Null END) AS [M],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 3 THEN Royalty_Sales ELSE 0 END) AS [Tu],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 3 THEN System_Date ELSE Null END) AS [Tu],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 4 THEN Royalty_Sales ELSE 0 END) AS [W],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 4 THEN System_Date ELSE Null END) AS [W],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 5 THEN Royalty_Sales ELSE 0 END) AS [Th],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 5 THEN System_Date ELSE Null END) AS [Th],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 6 THEN Royalty_Sales ELSE 0 END) AS [F],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 6 THEN System_Date ELSE Null END) AS [F],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 7 THEN Royalty_Sales ELSE 0 END) AS [Sa],
MAX(CASE WHEN DATEPART(weekday, System_Date) = 7 THEN System_Date ELSE Null END) AS [Sa]
FROM #myTable
GROUP BY Location_Code
ORDER BY Location_Code
I'd probably handle it with something like this...
;With myCTE
As
(
Select Location_Code
, System_Date
, Royalty_Sales
, DatePart(weekday, System_Date) As 'week_day'
From #myTable
)
Select Location_Code
, week_day
, Max(System_Date) As 'maxDay'
, Max(Royalty_Sales) As 'maxSales'
From myCTE
Group By Location_Code
, week_day;
Drop Table #myTable;
Hope that helps, let me know if you have any more questions.
Regards,
Michelle Ufford
SQLFool.com - Adventures in SQL Tuning
February 4, 2009 at 12:17 pm
Michell, thanks for your post.
However unless I did something wrong, max(System_Date) is simply throwing back whatever the most recent date is for each day of the week. For example, 2/4/2009 for a Wednesday.
Shawn
February 4, 2009 at 12:33 pm
Ah, I misread your initial question, sorry about that!
Try this:
Create Table #myTable
(
Location_Code int
, System_Date datetime
, Royalty_Sales int
);
Insert Into #myTable
Select 1, '2009-01-01', 100 Union All
Select 1, '2009-01-02', 300 Union All
Select 1, '2009-01-03', 250 Union All
Select 1, '2009-01-04', 100 Union All
Select 1, '2009-01-05', 100 Union All
Select 1, '2009-01-06', 100 Union All
Select 1, '2009-01-07', 100 Union All
Select 1, '2009-01-08', 200 Union All
Select 1, '2009-01-09', 100 Union All
Select 1, '2009-01-10', 150;
Select Location_Code
, DatePart(weekday, System_Date) As 'week_day'
, Max(Royalty_Sales) As 'maxSales'
, (Select Max(System_Date)
From #myTable As a
Where DatePart(weekday, a.System_Date) = DatePart(weekday, b.System_Date)
And a.Royalty_Sales = Max(b.Royalty_Sales)
) As 'maxDay'
From #myTable As b
Group By Location_Code
, DatePart(weekday, System_Date)
Drop Table #myTable;
Regards,
Michelle Ufford
SQLFool.com - Adventures in SQL Tuning
February 4, 2009 at 12:57 pm
Thanks Michelle. I actually learned a lot about nested queries in the process. I knew you could nest but comparing "a" to "b" in the manner you did was completely new. Thanks again.
Shawn
February 4, 2009 at 1:08 pm
That's great, I'm glad I could help! Just be careful when using correlated subqueries on large data sets, it can sometimes have a pretty big (negative) performance impact.
Good luck, and happy coding!
Regards,
Michelle Ufford
SQLFool.com - Adventures in SQL Tuning
Viewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy