我有一个包含产品ID和名称的表格,另一张表格包含某些日期的这些产品的库存。例如Item1
6
上的1-1-2014
库存和8
上的2-1-2014
库存。
我试图在存储过程中显示这些内容,使其看起来像一个日历,显示一个月中的所有日期以及单元格中可用的库存。展示这个的最佳方式是什么?
例如:
Name | 1-1-2014 | 2-1-2014 | 3-1-2014 | 4-1-2014
Item1 | 6 | 8 | | 6
Item2 | | 2 | 1 |
原始表格 - 名称
ID | Name
1 | Item1
2 | Item2
原始表格 - Stockdates
ID | NameID | Stock | Date
1 | 1 | 8 | 2-1-2014
2 | 2 | 2 | 4-1-2014
答案 0 :(得分:10)
这是您的示例表
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
将联接数据放入一个临时表
SELECT N.NAME,S.[DATE],S.STOCK
INTO #TABLE
FROM #NAMES N
JOIN #Stockdates S ON N.ID=S.NAMEID
获取数据透视列
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]
现在转动它
DECLARE @query NVARCHAR(MAX)
SET @query = '
SELECT * FROM
(
SELECT * FROM #TABLE
) x
PIVOT
(
SUM(STOCK)
FOR [DATE] IN (' + @cols + ')
) p
'
EXEC SP_EXECUTESQL @query
你的结果就在这里
答案 1 :(得分:2)
第1步 - 填补空白(可能不需要)
如果您的股票表每天不包含每种产品的库存,那么您必须从一个其他地方获得一个月内的所有日期。您可以使用递归CTE生成它们:(省略变量声明)
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;
您可以使用首选日期格式,但在所有查询中维护它是很重要的。
第2步 - 将数据转换为正常形式。您可以选择将其存储在临时表中,也可以再次使用CTE并将此步骤与步骤3结合使用。
使用dates
(完整)和products
(左)加入stock
(从上方),以便获得如下表格:
date
product_id
items
对于库存不可用的产品和日期,您显示0. isnull
将起作用。确保date
列转换为varchar
,格式与上述CTE相同。
第3步 - 在动态查询中按date
列旋转表格(在步骤2中获得)。
我可以给你更多细节但不是现在。 您可以在另一个响应中看到类似的内容: Spread distinct values over different columns