1

私は SQL に非常に慣れていないので、次のタスクを達成する方法がわかりません: テーブルに一連のデータがあり、そのデータを 2 つの値のいずれかに変換し、それぞれの合計を合計する必要があります。サマリー列のペアの行。下記参照:

tbl1:

row    P1    P2    P3
---    ---   ---   ---
1      a     b     c
2      a     a     a
3      b     c     b
4      a     b     b
5      NULL  NULL  NULL

変換表は次のとおりです。

PNum    PType
----    -----
a       car
b       truck
c       car

望ましい最終結果:

row    P1    P2    P3    numCars    numTrucks
---    ---   ---   ---   -------    ---------
1      a     b     c     2          1
2      a     a     a     3          0
3      b     c     b     1          2
4      a     b     b     1          2
5      NULL  NULL  NULL  NULL       NULL

テスト テーブルを取得するコード:

DECLARE @tbl1 TABLE(P1 VARCHAR,P2 VARCHAR,P3 VARCHAR)

INSERT INTO @tbl1
SELECT 'a','b','c' UNION ALL
SELECT 'a','a','a' UNION ALL
SELECT 'b','c','b' UNION ALL
SELECT 'a','b','b'


DECLARE @tbl2 TABLE(PNum VARCHAR,PType NVARCHAR(100))

INSERT INTO @tbl2
SELECT 'a','car' UNION ALL
SELECT 'b','truck' UNION ALL
SELECT 'c','car'

私は PIVOT を調べてきましたが、それを実装する方法を理解するのに苦労しています (特に変換ピースの場合)。最初に値を変換するためだけに一連の列を挿入しようと考えました (例: "P1_converted")、次にそれらを要約しようとしましたが、実際のテーブルにはこれらの型の列が 10 個あり、さらに 10 個の列を追加したくありませんでした。もっと簡単な方法があれば、テーブルに。何かご意見は?ありがとう!

SQL Server 2008 を使用しています。

4

2 に答える 2

1

を使用したわずかに異なるアプローチを次に示しPIVOTます。

SELECT * FROM 
(
  SELECT d.[row], d.P1, d.P2, d.P3, t.PType,
    [tc] = CASE WHEN t.PNum = d.P1 THEN 1 ELSE 0 END
         + CASE WHEN t.PNum = d.P2 THEN 1 ELSE 0 END
         + CASE WHEN t.PNum = d.P3 THEN 1 ELSE 0 END
  FROM @tbl1 d CROSS JOIN @tbl2 t
) AS x
PIVOT (SUM([tc]) FOR PType IN ([car],[truck])) AS p;
于 2013-03-29T18:40:58.570 に答える
1

以下を使用すると、データのピボットを解除して、車とトラックの合計数を取得できます。

関数を使用できUNPIVOTますが、SQL Server 2008 を使用しているため、 と を使用CROSS APPLYして、 、、およびを列から行VALUESに変換できます。データを変換するコードは次のとおりです。P1P2P3

select *
from tbl1 
cross apply 
(
  values ('p1', p1), ('p2', p2), ('p3', p3)
) c(col, value)

SQL Fiddle with Demoを参照してください。これにより、データが次の形式に変換されます。

| P1 | P2 | P3 | COL | VALUE |
------------------------------
|  a |  b |  c |  p1 |     a |
|  a |  b |  c |  p2 |     b |
|  a |  b |  c |  p3 |     c |
|  a |  a |  a |  p1 |     a |

データが行に入ったら、変換テーブルに簡単に結合して、各行のカウントを取得できます。

select rn, p1, p2, p3,
  sum(case when t.ptype = 'car' then 1 else 0 end) numCars,
  sum(case when t.ptype = 'truck' then 1 else 0 end) numTrucks
from
(
  select p1, p2, p3,
    row_number() over(order by p1, p2, p3) rn
  from tbl1
) d
cross apply (values ('p1', p1), ('p2', p2), ('p3', p3)) c(col, value)
inner join tbl2 t
  on c.value = t.pnum
group by rn, p1, p2, p3

SQL Fiddle with Demoを参照してください。これにより、次の結果が得られます。

| RN | P1 | P2 | P3 | NUMCARS | NUMTRUCKS |
-------------------------------------------
|  1 |  a |  a |  a |       3 |         0 |
|  2 |  a |  b |  b |       1 |         2 |
|  3 |  a |  b |  c |       2 |         1 |
|  4 |  b |  c |  b |       1 |         2 |
于 2013-03-29T18:19:55.850 に答える