我有两个表要合并。第一个表用于客户,其他表用于产品。目前,我有22种产品,但我希望有一个灵活的数据库设计,因此与其在产品数据库中没有22列,我为每个客户为每个产品提供1行,所以如果我总体上添加或删除1种产品,我不会必须更改数据库结构。
我想有一条select语句,在这里我为每个客户端选择所有产品,并且输出应该在一行中,每个产品都有一列。
我看到了其他一些类似的问题,但是这样做的目的是将所有行连接到1列中,这是我不想要的。
假设有2个客户和3个产品。
客户表:
ClientId | ClientName
---------------------
1 | Name1
2 | Name2
餐桌产品
ProductId | ClientId | Product
-------------------------------------
1 | 1 | SomeproductA
2 | 1 | SomeproductB
3 | 1 | SomeproductA
4 | 2 | SomeproductC
5 | 2 | SomeproductD
6 | 2 | SomeproductA
输出应该是这样的:
表输出:
ClientId | ClientName | Product1 | Product 2 | Product 3
-------------------------------------------------------------------
1 | Name1 | SomeproductA | SomeproductB | SomeproductA
2 | Name2 | SomeproductC | SomeproductD | SomeproductA
从select语句应该计算每个客户的不同产品的数量(对于所有客户而言,它们始终是相同的)的角度来看,完美的解决方案也是灵活的,例如,如果我为所有客户添加或删除1个产品,不应更改选择语句。
MYSQL版本
这是查询。联合查询使用用户定义的变量MySQL功能为每个客户端组内的每个产品生成RowNumber(1,2,3,...)。外部查询使用GROUP BY
CASE和内部表中的行号构成PIVOT表。如果您需要更改产品列数,请考虑动态创建此查询并将其添加MAX(CASE WHEN p.RowNum=X THEN p.Product END) as ProductX
到选择列表中。
select Clients.ClientName,
MAX(CASE WHEN p.RowNum=1 THEN p.Product END) as Product1,
MAX(CASE WHEN p.RowNum=2 THEN p.Product END) as Product2,
MAX(CASE WHEN p.RowNum=3 THEN p.Product END) as Product3,
MAX(CASE WHEN p.RowNum=4 THEN p.Product END) as Product4
FROM Clients
JOIN
(
SELECT Products.*,
if(@ClientId<>ClientId,@rn:=0,@rn),
@ClientId:=ClientId,
@rn:=@rn+1 as RowNum
FROM Products, (Select @rn:=0,@ClientId:=0) as t
ORDER BY ClientId,ProductID
) as P
ON Clients.ClientId=p.ClientId
GROUP BY Clients.ClientId
SQL Server版本:
select Clients.ClientId,
MAX(Clients.ClientName),
MAX(CASE WHEN p.RowNum=1 THEN p.Product END) as Product1,
MAX(CASE WHEN p.RowNum=2 THEN p.Product END) as Product2,
MAX(CASE WHEN p.RowNum=3 THEN p.Product END) as Product3,
MAX(CASE WHEN p.RowNum=4 THEN p.Product END) as Product4
FROM Clients
JOIN
(
SELECT Products.*,
ROW_NUMBER() OVER (PARTITION BY ClientID ORDER BY ProductID)
as RowNum
FROM Products
) as P
ON Clients.ClientId=p.ClientId
GROUP BY Clients.ClientId
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句