Mon SQL Fiddle est ici: 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);
Je voudrais écrire une requête pour returnner datatables client / entrepôt dans le format suivant:
Customer WH1 WH2 WH3 CustA wh01 CustB wh01 wh02 CustC wh01 wh02 wh03
Ma tentative pour ce faire renvoie null pour tous les entrepôts.
Comment puis-je build ma requête pour renvoyer datatables dans le format requirejs?
Pour get le résultat, vous devez JOINDRE les tables et appliquer la fonction PIVOT. Je suggère également d'utiliser la fonction de fenêtrage row_number()
pour get le nombre d'entrepôts pour chaque client – ce sera la valeur qui sera utilisée comme vos nouveaux en-têtes de colonnes.
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;
Voir SQL Fiddle avec démo . Si vous avez un nombre inconnu de valeurs, vous devrez utiliser le SQL dynamic pour get le résultat:
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;
Voir SQL Fiddle avec démo . Les deux donnent un résultat:
| CUSTOMERNAME | WH1 | WH2 | WH3 | | CustA | wh01 | (null) | (null) | | CustB | wh01 | wh02 | (null) | | CustC | wh01 | wh02 | wh03 |
Voici ce que j'ai trouvé après avoir vu l'exemple Complex PIVOT sur cette page MSDN :
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
Sur SQLFiddle: http://sqlfiddle.com/#!3/d5c60/42