sql >> データベース >  >> RDS >> Sqlserver

動的列 - SQL Server - 列としての月

    データは既にピボットされていますが、別のレベルでピボットする必要があります。これを処理する最善の方法は、最初にピボットを解除し、次に正しいピボット レベルを処理することだと思います。

    ステップ 1:ピボットを解除する

    SQL 2005 UNPIVOT を使用できます。 コマンドを使用するか、CROSS JOIN 手法を使用します。両方の例を次に示します。単純にするために、途中の月を省略したことに注意してください。追加するだけです。

    -- CROSS JOIN method (also works in SQL 2000)
    SELECT
       P.Project,
       Mo =
          DateAdd(mm,
             X.MonthNum,
             DateAdd(yy, P.[Year] - 1900, '19000101')
          ),
       Amount = 
          CASE X.MonthNum
             WHEN 0 THEN Jan
             WHEN 1 THEN Feb
             WHEN 11 THEN Dec
          END
    FROM
       ProjectData P
       CROSS JOIN (
          SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 11
       ) X (MonthNum)
    

    各行は 12 回繰り返され、CASE ステートメントは行ごとに 1 か月だけを引き出し、データを適切にピボット処理しないままにします。

    -- UNPIVOT method
    SELECT
        P.Project,
        Mo =
           DateAdd(mm,
              Convert(int, P.MonthNum),
              DateAdd(yy, P.[Year] - 1900, '19000101')
           ),
        P.Amount
    FROM
       (
          SELECT Project, [Year], [0] = Jan, [1] = Feb, [11] = Dec
          FROM ProjectData
       ) X UNPIVOT (Amount FOR MonthNum IN ([0], [1], [11])) P
    
    DROP TABLE ProjectData
    

    どちらの方法も常に明確なパフォーマンスの勝者ではありません。場合によっては、一方が他方よりもうまく機能することがあります (ピボットされるデータによって異なります)。 UNPIVOT メソッドは、CROSS JOIN が使用しない実行計画でフィルターを使用します。

    ステップ 2:再びピボット

    次に、ピボットされていないデータの使用方法について説明します。あなたの誰かが これを消費しますが、データを何らかの出力ファイルに入れる必要があるため、追加料金なしで SQL Server 2005 に付属している SSRS (Sql Server Reporting Services) を使用することをお勧めします。

    マトリックス を使用するだけです レポート オブジェクトを使用して、上記のクエリのいずれかをピボットします。このオブジェクトは、レポートの実行時に列ラベルにするデータ値を喜んで決定し、まさに必要なもののように聞こえます。日付を好きなように書式設定する列を追加すると、Mo 列で並べ替えることができますが、新しい式を列ラベルとして使用できます。

    SSRS には、さまざまな形式とスケジューリング オプションも用意されています。たとえば、Excel ファイルを電子メールで送信したり、Web ページをファイル共有に保存したりできます。

    抜けているものがあれば教えてください。

    上記のコードの動作を確認したい方のために、作成スクリプトをいくつか示します:

    USE tempdb
    
    CREATE TABLE ProjectData (
        Project varchar(10),
        [Year] int,
        Jan decimal(15, 2),
        Feb decimal(15, 2),
        Dec decimal(15, 2)
    )
    
    SET NOCOUNT ON
    
    INSERT ProjectData VALUES ('11-11079', 2008, 0.0, 0.0, 75244.90)
    INSERT ProjectData VALUES ('11-11079', 2009, 466.0, 0.0, 0.0)
    INSERT ProjectData VALUES ('11-11079', 2010, 855.0, 0.0, 0.0)
    INSERT ProjectData VALUES ('01-11052', 2009, 56131.0, 0.0, 0.0)
    


    1. MySQL INSERT else(存在する場合)UPDATE

    2. mysql指定された値のセットですべての行の列を更新する方法

    3. 明確な値をすばやく見つける

    4. 日付に基づいて最新の5行を選択します