我在选择GROUP BY
子句生成的多个值时遇到问题。
我尝试建立一个简化的例子:
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
由此我可以将每个产品和每个客户加入一个单元格
Results
PROMO | products | CUSTOMERS
-------+--------------+--------------------
gold | prod1, prod2 | Alice, Bob, Charlie
silver | prod3 | Alice
类似的东西:
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
这可以在SQL中实现吗?
答案 0 :(得分:1)
你可以使用它。
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)
结果:
PROMO products CUSTOMERS
---------- -------------- -------------------------
gold prod1,prod2 Alice,Bob,Charlie
silver prod3 Alice