I have a table with product id's and names, and another table with the stock of these products on certain dates. Such as Item1
had 6
stock on 1-1-2014
and 8
stock on 2-1-2014
.
I'm trying to show these in a stored procedure so that it looks like a calendar, showing all the dates in a month and the stock available in the cells. What is the best way to show this?
For example:
Name | 1-1-2014 | 2-1-2014 | 3-1-2014 | 4-1-2014
Item1 | 6 | 8 | | 6
Item2 | | 2 | 1 |
Original tables - Names
ID | Name
1 | Item1
2 | Item2
Original tables - Stockdates
ID | NameID | Stock | Date
1 | 1 | 8 | 2-1-2014
2 | 2 | 2 | 4-1-2014
Here is your sample table
SELECT * INTO #Names
FROM
(
SELECT 1 ID,'ITEM1' NAME
UNION ALL
SELECT 2 ID,'ITEM2' NAME
)TAB
SELECT * INTO #Stockdates
FROM
(
SELECT 1 ID,1 NAMEID,8 STOCK,'2-1-2014 ' [DATE]
UNION ALL
SELECT 2 ID,2 NAMEID,2 STOCK,'4-1-2014 ' [DATE]
)TAB
Put the join data to a temperory table
SELECT N.NAME,S.[DATE],S.STOCK
INTO #TABLE
FROM #NAMES N
JOIN #Stockdates S ON N.ID=S.NAMEID
Get the columns for pivot
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + CONVERT(NVARCHAR, [DATE], 106) + ']',
'[' + CONVERT(NVARCHAR, [DATE], 106) + ']')
FROM (SELECT DISTINCT [DATE] FROM #TABLE) PV
ORDER BY [DATE]
Now pivot it
DECLARE @query NVARCHAR(MAX)
SET @query = '
SELECT * FROM
(
SELECT * FROM #TABLE
) x
PIVOT
(
SUM(STOCK)
FOR [DATE] IN (' + @cols + ')
) p
'
EXEC SP_EXECUTESQL @query
And your result is here
Step 1 - Fill the gaps (maybe not required)
If your stocks table does not contain stock from every day for every product then you have to get all the dates in a month from somewhere else. You can generate them with a recursive CTE: (variable declarations are omitted)
with dates as
(
select @startdate as [date]
union ALL
select [date] + 1
from dates
where [date] < @enddate
)
select @strDays = COALESCE(@strDays + ', ['+ convert(varchar(8), [date],112) + ']', '['+ convert(varchar(8), [date],112) + ']')
from dates;
You can use your preferred date format but it's important to maintain it in all queries.
Step 2 - Bring data to a normal form. You can chose to store it in a temporary table or you can use a CTE again and combine this step with step 3.
Join dates
(from above) with products
(full) and with stock
(left) so you obtain a table like this:
date
product_id
items
For products and dates where stock is not available you display 0. isnull
will do the trick. Make sure the date
column is converted to varchar
in the same format as in CTE above.
Step 3 - pivot the table (obtained at step 2) by date
column in a dynamic query.
I can give you more details but not right now. You can see something similar in another response: Spread distinct values over different columns
来源:https://stackoverflow.com/questions/27422109/how-to-pivot-dynamically-with-date-as-column