Reputation: 2031
I have a table that has a week_id and net_sales for that week (as well as a lot of other columns).
style_number, week_id, net_sales ABCD, 1, 100.00 ABCD, 2, 125.00 EFGH, 1, 50.00 EFGH, 2, 75.00
I am trying to write a statement that will list the
style_number, net_sales
for the
MAX(week_id), net_sales for the MAX(week_id)-1 .... , MAX(week_id) - n
So that the results look like:
ABCD, 125.00, 100.00 EFGH, 75.00, 50.00
What is the best way to approach this, especially when n can be rather large (i.e. looking back 52 weeks)?
I hope this makes sense! I am using SQL Server 2008 R2. Thanks a lot in advance!
Upvotes: 1
Views: 92
Reputation: 2258
You might consider using the PIVOT
command: http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
OR
If you are okay with the result being a comma separated list, you could use the STUFF
and FOR XML
commands like so.
SELECT DISTINCT
style_name,
STUFF(
(SELECT ',' + CAST(net_sales AS VARCHAR(20))
FROM MyTable AS SubTable
WHERE SubTableUser.style = MyTable.style_name
ORDER BY week_id DESC --DESC will get your max ID to be first
FOR XML PATH('')), 1, 1, '') AS net_sales_list
FROM MyTable
ORDER BY style_name
This will provide you with:
style_name | net_sales_list
---------------------------
ABCD | 100.00,125.00
EFGH | 75.00,50.00
Upvotes: 0
Reputation: 92845
You can use PIVOT
and dynamic SQL to deal with your large number of weeks
DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)
SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(week_id)
FROM sales
ORDER BY 1 DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @sql = 'SELECT style_number, ' + @cols +
' FROM
(
SELECT style_number, week_id, net_sales
FROM sales
) x
PIVOT
(
MAX(net_sales) FOR week_id IN (' + @cols + ')
) p
ORDER BY style_number'
EXECUTE(@sql)
Here is SQLFiddle demo.
Upvotes: 1
Reputation: 62861
If you know the number of weeks, since you are using SQL Server 2008, you can use the PIVOT
command, or you can use MAX
with CASE
:
Here's an example using MAX
with CASE
:
select
style_number,
max(case when week_id = 2 then net_sales end) week2sales,
max(case when week_id = 1 then net_sales end) week1sales
from yourtable
group by style_number
If you do not know the number of weeks, you'll need to look into using dynamic SQL. Just do a search, lots of posts on SO on it.
Upvotes: 0