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

SQL - 集計なしで複数の列をピボットする

    問題の一部は、ピボットしたい複数の列にわたって非正規化されたデータがあることです。理想的には、テーブル構造を修正して、保守とクエリが容易になるようにすることを検討する必要があります。テーブル構造を修正できない場合は、最初に列のピボットを解除してから PIVOT を適用して最終結果を取得する必要があります。

    UNPIVOT プロセスは、複数の列を取得して複数の行に変換します。 SQL Server のバージョンに応じて、これを行う方法がいくつかあります。 UNPIVOT 関数を使用するか、SQL Server 2008 を使用しているため、VALUES 句を指定して CROSS APPLY を使用してピボットを解除できます。

    CROSS APPLY/VALUES コードは次のようになります:

    select t.producttitle, c.col, c.valuefrom tmpData tcross apply( values (abvrMonthName, MonthAvg), (abvrMonthNameCount, MonthCount)) c (col, value)  

    SQL Fiddle with Demo を参照してください。 .これにより、複数の列が取得され、データが次のような形式になります:

    <プレ>|製品タイトル |コール |値 |-------------------------------------|製品 1 | 12月 | 0 ||製品 1 | 12月号 | 0 ||製品 1 | 11月 | 0 ||製品 1 | 11月号 | 0 ||製品 1 | 10月 | 0 ||製品 1 | 10月号 | 0 ||製品 1 | 9月 | 0 ||製品 1 | 9月号 | 0 |

    データがこの形式になったら、col の値に PIVOT を適用できます。 月名を含む:

    select producttitle, jan, [jan#], feb, [feb#], mar, [mar#], apr, [apr#], may, [may#], jun, [jun#] 、7月、[7月#]、8月、[8月#]、9月、[9月#]、10月、[10月#]、11月、[11月#]、12月、[12月#]from( select t.producttitle, c .col, c.value from tmpData t cross apply ( values (abvrMonthName, MonthAvg), (abvrMonthNameCount, MonthCount) ) c (col, value)) dpivot( sum(value) for col in (jan, [jan#], feb 、[2月#]、3月、[3月#]、4月、[4月#]、5月、[5月#]、6月、[6月#]、7月、[7月#]、8月、[8月#]、9月、 [sep#]、oct、[oct#]、nov、[nov#]、dec、[dec#])) piv;  

    デモによる SQL Fiddle を参照してください。 .これにより結果が得られます:

    <プレ>|製品タイトル | 1月 | 1月号 | 2月 | 2月号 | 3月 | 3月号 | 4月 | 4月号 | 5月 | 5 月号 |じゅん | 6月号 | 7月 | 7月号 | 8月 | 8月号 | 9月 | 9 月番号 | 10 月 | 10月号 | 11月 | 11月号 | 12月 | DEC# |-------------------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------------|製品 1 | 5 | 2 | 5 | 1 | 5 | 4 | 5 | 6 | 4.44 | 9 | 5 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ||製品 2 | 0 | 0 | 0 | 0 | 0 | 0 | 4.33 | 3 | 4.67 | 3 | 5 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ||製品 3 | 4.6 | 5 | 4.75 | 8 | 4.75 | 8 | 4 | 6 | 5 | 6 | 5 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |


    1. SQL FLOAT:奇妙な数学エラーを回避するのに役立つ3つのポイント

    2. Mysql SelectRows2つの列が同じ値を持たない場合

    3. SQLは、パラメーターがnullの場合はすべて選択し、それ以外の場合は特定の項目を返します

    4. Oracle/SQL-指定された範囲の順次レコードを選択します