6

私のSQLフィドルはここにあります:http://sqlfiddle.com/#!3/d5c60

CREATE TABLE customer 
    (
     id int identity primary key, 
     name varchar(20), 
    );

CREATE TABLE warehouse 
    (
     id int identity primary key, 
     name varchar(20), 
    );

CREATE TABLE customerwarehouse 
    (
     id int identity primary key, 
     customerid int,
      warehouseid int
    );

INSERT INTO customer (name) 
VALUES
('CustA'),
('CustB'),
('CustC');

INSERT INTO warehouse (name) 
VALUES
('wh01'),
('wh02'),
('wh03');

INSERT INTO customerwarehouse (customerid, warehouseid)
VALUES
(1,1),
(2,1),
(2,2),
(3,1),
(3,2),
(3,3);

次の形式で顧客/倉庫データを返すクエリを書きたいと思います。

Customer    WH1    WH2    WH3
CustA       wh01    
CustB       wh01   wh02
CustC       wh01   wh02   wh03

これを実行しようとすると、すべての倉庫で null が返されます。

必要な形式でデータを返すようにクエリを作成するにはどうすればよいですか?

4

2 に答える 2

5

結果を取得するには、テーブルを結合して PIVOT 関数を適用します。ウィンドウ関数を使用して、各顧客の倉庫数を取得することもお勧めしrow_number()ます。これは、新しい列ヘッダーとして使用される値になります。

select customername, wh1, wh2, wh3
from
(
  select w.name warehousename,
    c.name customername,
    'wh'+cast(row_number() over(partition by c.id
                                order by w.id) as varchar(10)) seq
  from customer c
  inner join customerwarehouse cw
    on c.id = cw.customerid
  inner join warehouse w
    on cw.warehouseid = w.id
) d
pivot
(
  max(warehousename)
  for seq in (wh1, wh2, wh3)
) piv;

SQL Fiddle with Demoを参照してください。値の数が不明な場合は、動的 SQL を使用して結果を取得する必要があります。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('wh'+cast(row_number() over(partition by customerid
                                                                                  order by warehouseid) as varchar(10))) 
                    from customerwarehouse
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT customername, ' + @cols + ' 
            from 
            (
                select w.name warehousename,
                  c.name customername,
                  ''wh''+cast(row_number() over(partition by c.id
                                              order by w.id) as varchar(10)) seq
                from customer c
                inner join customerwarehouse cw
                  on c.id = cw.customerid
                inner join warehouse w
                  on cw.warehouseid = w.id
            ) x
            pivot 
            (
                max(warehousename)
                for seq in (' + @cols + ')
            ) p '

execute sp_executesql @query;

SQL Fiddle with Demoを参照してください。両方とも結果が得られます。

| CUSTOMERNAME |  WH1 |    WH2 |    WH3 |
|        CustA | wh01 | (null) | (null) |
|        CustB | wh01 |   wh02 | (null) |
|        CustC | wh01 |   wh02 |   wh03 |
于 2013-09-10T18:17:56.660 に答える
0

このMSDNページの複雑なPIVOTの例を見た後、私が思いついたのは次のとおりです。

SELECT
  CustomerName,
  case when [wh01] is null then null else 'wh01' end,
  case when [wh02] is null then null else 'wh02' end,
  case when [wh03] is null then null else 'wh03' end
FROM (
  SELECT
    c.Name AS CustomerName,
    cw.id AS cwid,
    w.name AS WarehouseName
  FROM Customer c
  JOIN CustomerWarehouse cw
    ON c.id = cw.customerId
  JOIN Warehouse w
    ON w.id = cw.warehouseId
) AS SourceTable
pivot (
  max(cwid)
  FOR WarehouseName IN (
      [wh01], [wh02], [wh03]
    )
) AS PivotTable

SQLFiddle の場合: http://sqlfiddle.com/#!3/d5c60/42

于 2013-09-10T18:22:47.927 に答える