3

複数の行と列を持つテーブルのピボットを解除しようとしています。各行は、特定の列を含む 2 つの行に抽出する必要があり、列名の名前を変更し、選択した列に基づいて新しい列を追加する必要があります。

前後のサンプル データと、データをセットアップするためのスクリプトを含めています。

 CREATE TABLE #tmpProducts (
        ProductId INT,
        ProductName nVARCHAR(100),
        B2B_GrossRevenue DECIMAL(10,2),
        B2B_DirectCost DECIMAL(10,2),
        B2B_NetRevenue DECIMAL(10,2),
        B2C_GrossRevenue DECIMAL(10,2),
        B2C_DirectCost DECIMAL(10,2),
        B2C_NetRevenue DECIMAL(10,2)
    )

    INSERT INTO #tmpProducts SELECT 1, 'Product1',1545.00,406.25,1138.75,195.00,35.10,159.90
    INSERT INTO #tmpProducts SELECT 2, 'Product2',902.00,189.00,713.00,3280.00,590.40,2689.60
    INSERT INTO #tmpProducts SELECT 3, 'Product3',15665.00,3988.39,11676.61,6247.00,1124.46,5122.54
    INSERT INTO #tmpProducts SELECT 4, 'Product4',736.00,196.16,539.84,2395.00,431.10,1963.90

    SELECT * FROM #tmpProducts
    DROP TABLE #tmpProducts

    CREATE TABLE #tmpProducts2 (
        ProductId INT,
        ProductName nVARCHAR(100),
        [Type] nVARCHAR(3),
        GrossRevenue DECIMAL(10,2),
        DirectCost DECIMAL(10,2),
        NetRevenue DECIMAL(10,2)
    )

    INSERT INTO #tmpProducts2 SELECT 1, 'Product1','B2B',1545.00,406.25,1138.75
    INSERT INTO #tmpProducts2 SELECT 1, 'Product1','B2C',195.00,35.10,159.90
    INSERT INTO #tmpProducts2 SELECT 2, 'Product2','B2B',902.00,189.00,713.00
    INSERT INTO #tmpProducts2 SELECT 2, 'Product2','B2C',3280.00,590.40,2689.60
    INSERT INTO #tmpProducts2 SELECT 3, 'Product3','B2B',15665.00,3988.39,11676.61
    INSERT INTO #tmpProducts2 SELECT 3, 'Product3','B2C',6247.00,1124.46,5122.54
    INSERT INTO #tmpProducts2 SELECT 4, 'Product4','B2B',736.00,196.16,539.84
    INSERT INTO #tmpProducts2 SELECT 4, 'Product4','B2C',2395.00,431.10,1963.90

    SELECT * FROM #tmpProducts2
    DROP TABLE #tmpProducts2

私はこれを試みましたが、2番目の列を通過できず、特定のテキストを含む新しい列を追加する方法がわかりません(おそらく動的SQLですが、可能であればこれを回避しようとしています)

これが私の試みの始まりです。どんな助けでも大歓迎です。

SELECT  ProductId, ProductName,GrossRevenue
        FROM    (
                    SELECT ProductId, ProductName, B2B_GrossRevenue,B2C_GrossRevenue FROM #tmpProducts
                ) as t
            UNPIVOT ( GrossRevenue for test IN (B2B_GrossRevenue,B2C_GrossRevenue)) AS unpvt
4

3 に答える 3

5

あなたはただピボットを外し続けます

    SELECT  ProductId,ProductName, Substring(col1,1,3) as type,  GrossRevenue, DirectCost, NetRevenue
    FROM    ( 
        SELECT * FROM #tmpProducts 
    ) as t 
    UNPIVOT ( GrossRevenue for col1 IN (B2B_GrossRevenue,B2C_GrossRevenue)) AS unpvt 
    unpivot ( DirectCost for col2 in (B2b_DirectCost, B2c_DirectCost)) up2
    unpivot ( NetRevenue for col3 in (B2b_NetRevenue, B2c_NetRevenue)) up3
where SUBSTRING(col1,1,3)=SUBSTRING(col2,1,3)
and  SUBSTRING(col1,1,3)=SUBSTRING(col3,1,3)

col 列を結合して、不一致を除外します

于 2012-08-09T10:19:30.653 に答える
2

動的 SQL を使用してこれを行う方法を次に示します。これにより、実行時にすべての列を取得できます。これにより、データが変更された場合にクエリを変更する必要がなくなります。これは と の両方をUNPIVOT行いPIVOTます:

DECLARE @colsUnPivot AS NVARCHAR(MAX),
    @colsPivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

SET @colsUnPivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('tmpProducts') and
               C.name like 'B2%'
         for xml path('')), 1, 1, '')

SET @colsPivot = stuff((select DISTINCT ','+quotename(right((C.name), len(C.name)-4))
         from sys.columns as C
         where C.object_id = object_id('tmpProducts') and
               C.name like 'B2%'
         for xml path('')), 1, 1, '')


set @query 
  = ' SELECT ProductId, ProductName, [type], ' + @colsPivot +'
      FROM
      (
        SELECT ProductId, ProductName, substring(field, 1, 3) [type]
                ,  value, right((field), len(field)-4) as col
        from tmpProducts
        unpivot 
        (
           value
           for field in (' + @colsUnPivot + ')
        ) unpvt 
      ) x
      PIVOT
      (
        sum(value)
        FOR col IN (' + @colsPivot +')
      )p'


execute(@query)

デモで SQL Fiddle を参照してください

于 2012-08-09T10:55:15.907 に答える
0

ピボットしたいグループが複数ある場合は、次のようなこともできます。

Select *
  from table
  unpivot include nulls ( (test_name, test_date) for col_nm in ( (test1, date1) as 'test_val1'
                                                                ,(test2, date2) as 'test_val2'
                                                                ,(test3, date3) as 'test_val3'
                                                               )
                     )
于 2014-01-10T20:20:09.340 に答える