web-dev-qa-db-ja.com

日付を列として動的にピボットする方法

製品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 
11
Craphex

ここにあなたのサンプルテーブルがあります

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

そしてあなたの結果はここにあります

enter image description here

16
Sarath Avanavu

ステップ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で取得)をピボットします。

詳細についてはお伝えできますが、現時点ではお伝えできません。別の応答で同様のものが表示されます: 異なる列に異なる値を分散

2
B0Andrew