2017-12-18 2 views
0

Ich habe Probleme bei der Auswahl mehrerer Werte durch eine GROUP BY Klausel generiert. Ich versuche, ein vereinfachtes Beispiel einzurichten, was ich habe:Unterabfrage mit jedem Wert in der Gruppe von

Table CUSTOMERS Table PRODUCTS   Table ORDERS 
ID | NAME   ID | DESCR | PROMO   ID_P | ID_C 
---+---------  ---+-------+-------  -----+----- 
1 | Alice   1 | prod1 | gold   1 | 1 
2 | Bob   2 | prod2 | gold   2 | 3 
3 | Charlie  3 | prod3 | silver   1 | 2 
        4 | prod4 | silver   3 | 1 

Daraus würde ich lik jedes Produkt und jeden Kunden in einer einzigen Zelle

Results 
PROMO | products  | CUSTOMERS 
-------+--------------+-------------------- 
gold | prod1, prod2 | Alice, Bob, Charlie 
silver | prod3  | Alice 

So etwas verbinden:

SELECT PRODUCTS.PROMO 
    , CONCAT(PRODUCTS.DESCR) 
    , STUFF(
     (SELECT '/' + CUSTOMERS.NAME 
      FROM CUSTOMERS 
      WHERE CUSTOMERS.ID = ORDERS.ID 
      FOR XML PATH ('')) 
     , 1, 3, '') 
FROM  PRODUCTS 
INNER JOIN ORDERS 
ON PRODUCTS.ID = ORDERS.ID_P 
WHERE PRODUCTS.ID < 3 
GROUP BY PRODUCTS.PROMO 

Kann dies in SQL erreicht werden?

+0

https://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-microsoft-sql-server-2005 – jarlh

+0

@jarlh: Danke, ich habe mit diesem Post angefangen, aber ich bekomme, dass CUSTOMER.NAME in der Auswahlliste ungültig ist, weil es nicht in GROUP BY enthalten ist, aber ich möchte nicht nach Kunde oder nach Produkt gruppieren – dg3

Antwort

1

Sie können dies verwenden.

DECLARE @CUSTOMERS Table(ID INT, NAME VARCHAR(20)) 
INSERT INTO @CUSTOMERS VALUES 
(1 ,'Alice'),    
(2 ,'Bob'),    
(3 ,'Charlie')    

DECLARE @PRODUCTS TABLE (ID INT, DESCR VARCHAR(10), PROMO VARCHAR(10)) 
INSERT INTO @PRODUCTS VALUES 
(1 ,'prod1','gold'), 
(2 ,'prod2','gold'), 
(3 ,'prod3','silver'), 
(4 ,'prod4','silver') 

DECLARE @ORDERS TABLE ( ID_P INT, ID_C INT) 
INSERT INTO @ORDERS VALUES 
( 1 ,1), 
( 2 ,3), 
( 1 ,2), 
( 3 ,1) 


;WITH CTE AS (
SELECT O.*, P.PROMO, P.DESCR, C.NAME FROM @ORDERS O 
INNER JOIN @PRODUCTS P ON O.ID_P = P.ID 
INNER JOIN @CUSTOMERS C ON O.ID_C = C.ID 
) 
SELECT DISTINCT T.PROMO, 
    STUFF(Product.Descrs,1,1,'') products, 
    STUFF(Customer.Names,1,1,'') CUSTOMERS 
FROM CTE T 
    CROSS APPLY (SELECT DISTINCT ',' + T1.DESCR FROM CTE T1 WHERE T.PROMO = T1.PROMO FOR XML PATH('')) AS Product(Descrs) 
    CROSS APPLY (SELECT DISTINCT ',' + T1.NAME FROM CTE T1 WHERE T.PROMO = T1.PROMO FOR XML PATH('')) AS Customer(Names) 

Ergebnis:

PROMO  products  CUSTOMERS     
---------- -------------- ------------------------- 
gold  prod1,prod2 Alice,Bob,Charlie 
silver  prod3   Alice 
+0

Vielen Dank! Ich denke, ich muss das CROSS APPLY gut lernen! – dg3

Verwandte Themen