製品IDと名前のテーブルと、特定の日付のこれらの製品の在庫の別のテーブルがあります。といった Item1
持っていました 6
在庫あり1-1-2014
および8
在庫あり2-1-2014
。これらをストアドプロシージャで表示して、1か月のすべての日付とセルで利用可能な在庫を表示するカレンダーのように表示しようとしています。これを示す最良の方法は何ですか?
例:
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
ここにあなたのサンプルテーブルがあります
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-ギャップを埋める(おそらく必要ない)
Stocksテーブルに、すべての製品の毎日の在庫が含まれていない場合、月のすべての日付をどこかから取得する必要があります。再帰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
列が上記のCTEと同じ形式でvarchar
に変換されていることを確認してください。
ステップ3-動的クエリのdate
列でテーブル(ステップ2で取得)をピボットします。
詳細についてはお伝えできますが、現時点ではお伝えできません。別の応答で同様のものが表示されます: 異なる列に異なる値を分散