26

次の課題に直面しています。同じ列でテーブル データを 2 回ローテーションする必要があります。これがデータのスクリーンショットです。

アイテムが販売された各年の購入価格と販売価格を含むアイテムのリスト

毎年の購入額と販売額の両方を含むアイテム ID ごとに 1 つの行が必要です。「年」列を 2 回選択し、各販売年が「S」で始まり、各購入年が「P」で始まるように少しフォーマットし、2 つのピボットを使用して 2 年の列を回転させることで、これを行ってみました。 . SQL クエリは次のとおりです (SQL Server 2008 で使用)。

SELECT [Item ID], 
        [P2000],[P2001],[P2002],[P2003],
        [S2000],[S2001],[S2002],[S2003]
FROM 
(

SELECT [Item ID]
      ,'P' + [Year] AS YearOfPurchase
      ,'S' + [Year] AS YearOfSelling

  ,[Purchasing value]
  ,[Selling value]
  FROM [ItemPrices]
) AS ALIAS

PIVOT 
(
MIN ([Purchasing value]) FOR [YearOfPurchase] in ([P2000],[P2001],[P2002],[P2003])
)
AS pvt

PIVOT 
(
MIN ([Selling value]) FOR [YearOfSelling] in ([S2000],[S2001],[S2002],[S2003])
)
AS pvt2

結果は、まさに私が望んでいたものではありません (下の画像を参照)。

実際の状況: 行が多すぎる

ご覧のとおり、各アイテム ID にはまだ複数の行があります。行数をアイテムごとに正確に 1 つに減らす方法はありますか? 下の Excel のスクリーンショットのように見えますか?

望ましい状況: アイテム ID ごとに 1 行

4

3 に答える 3

30

私の提案はUNPIVOT、関数とPIVOT関数の両方を適用して結果を取得することです。

は、列と列を行に変換しますUNPIVOT。これが完了したら、データを結果にピボットできます。PurchasingValueSellingValue

コードは次のようになります。

select *
from
(
  select itemid, 
    case 
      when col = 'PurchasingValue' then 'P'
      when col = 'SellingValue' then 'S'
    end + cast(year as varchar(4)) new_col,
    value
  from yourtable
  unpivot
  (
    value
    for col in ([PurchasingValue], [SellingValue])
  ) unpiv
) src
pivot
(
  max(value)
  for new_col in (P2000, P2001, P2002, P2003,
                  S2000, S2001, S2002, S2003)
) piv;

SQL Fiddle with Demoを参照してください。結果は次のとおりです。

| ITEMID | P2000 | P2001 | P2002 | P2003 | S2000 | S2001 | S2002 | S2003 |
--------------------------------------------------------------------------
|      1 |  1000 |  1100 |  1200 |  1300 |   900 |   990 |  1080 |  1170 |
|      2 |   500 |   550 |   600 |   650 |   450 |   495 |   540 |   585 |

SQL Server 2008+ では、関数とともに withCROSS APPLYを使用できます。VALUESPIVOT

select *
from
(
  select itemid,
    col+cast(year as varchar(4)) new_col,
    value
  from yourtable
  cross apply
  (
    VALUES
        (PurchasingValue, 'P'),
        (SellingValue, 'S')
   ) x (value, col)
) src
pivot
(
  max(value)
  for new_col in (P2000, P2001, P2002, P2003,
                  S2000, S2001, S2002, S2003)
) piv

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

于 2013-03-07T15:23:03.303 に答える
11

複数の列をピボットする簡単な方法の 1 つは、Aggregate(Case) 式を使用することです。

SELECT  [Item ID],
        [P2000] = SUM(CASE WHEN [Year] = 2000 THEN [Purchasing value] END),
        [P2001] = SUM(CASE WHEN [Year] = 2001 THEN [Purchasing value] END),
        [P2002] = SUM(CASE WHEN [Year] = 2002 THEN [Purchasing value] END),
        [P2003] = SUM(CASE WHEN [Year] = 2003 THEN [Purchasing value] END),
        [S2000] = SUM(CASE WHEN [Year] = 2000 THEN [Selling value] END),
        [S2001] = SUM(CASE WHEN [Year] = 2001 THEN [Selling value] END),
        [S2002] = SUM(CASE WHEN [Year] = 2002 THEN [Selling value] END),
        [S2003] = SUM(CASE WHEN [Year] = 2003 THEN [Selling value] END)
FROM    ItemPrices
GROUP BY [Item ID]
于 2016-09-01T19:03:17.487 に答える
5

各結果列で集計関数 SUM(isnull(value,0)) を使用して、GROUP BY ItemID を使用します。

于 2013-03-07T15:11:58.840 に答える