如何将不同的产品转换为以计数为值的列
How to turn distinct products into columns with the count as value
我有一个 table,其中包含客户 ID 和他们购买的产品:
CustomerId
Product
3
Apple
3
Orange
3
Banana
7
Orange
7
Orange
7
Banana
9
Apple
9
Apple
9
Banana
我想为每个客户创建一个列,其中包含他们购买的每个不同值的产品数量:
CustomerId
Apple
Orange
Banana
3
1
1
1
7
0
2
1
9
2
0
1
出于某种原因,我无法在网上找到类似的问题,我怀疑这是由于我无法提出问题。
今天我了解了动态 PIVOT 查询 - 将列转换为行。结合动态查询(其内容直到运行时才完全知道的查询),您可以在不知道列中所有值的情况下使用 PIVOT 查询,方法是在运行时将值添加到查询中。
以我的问题为例:
创建并填充问题中的第一个 table,我们将其称为销售:
DROP TABLE IF EXISTS #Sales
CREATE TABLE #Sales
(
CustomerID INT,
Product NVARCHAR(255) NOT NULL
);
INSERT #Sales VALUES
(3, N'Apple'),
(3, N'Orange'),
(3, N'Banana'),
(7, N'Orange'),
(7, N'Orange'),
(7, N'Banana'),
(9, N'Apple'),
(9, N'Apple'),
(9, N'Banana');
按 CustomerID 和 Product 分组计算每种产品的购买量:
SELECT CustomerID
, Product
, COUNT(*) as Total_bought
INTO #SalesSummed
FROM #Sales
GROUP BY CustomerID, Product
将每个不同的产品添加到数据透视查询:
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(Product)
FROM (SELECT p.Product FROM #SalesSummed AS p
GROUP BY p.Product) AS x;
SET @sql = N'
SELECT p.CustomerID, ' + STUFF(@columns, 1, 2, '') + '
INTO #SalesMatrix
FROM
(
SELECT p.CustomerID, p.Product, p.Total_bought
FROM #SalesSummed AS p
) AS j
PIVOT
(
SUM(Total_bought) FOR Product IN ('
+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT @sql;
EXEC sp_executesql @sql;
第 3 步产生 table SalesMatrix:
CustomerID
Apple
Banana
Orange
3
1
1
1
7
NULL
1
2
9
2
1
NULL
这正是我们想要的(我们可以用 0 替换 NULL)!
我有一个 table,其中包含客户 ID 和他们购买的产品:
CustomerId | Product |
---|---|
3 | Apple |
3 | Orange |
3 | Banana |
7 | Orange |
7 | Orange |
7 | Banana |
9 | Apple |
9 | Apple |
9 | Banana |
我想为每个客户创建一个列,其中包含他们购买的每个不同值的产品数量:
CustomerId | Apple | Orange | Banana |
---|---|---|---|
3 | 1 | 1 | 1 |
7 | 0 | 2 | 1 |
9 | 2 | 0 | 1 |
出于某种原因,我无法在网上找到类似的问题,我怀疑这是由于我无法提出问题。
今天我了解了动态 PIVOT 查询 - 将列转换为行。结合动态查询(其内容直到运行时才完全知道的查询),您可以在不知道列中所有值的情况下使用 PIVOT 查询,方法是在运行时将值添加到查询中。
以我的问题为例:
创建并填充问题中的第一个 table,我们将其称为销售:
DROP TABLE IF EXISTS #Sales CREATE TABLE #Sales ( CustomerID INT, Product NVARCHAR(255) NOT NULL ); INSERT #Sales VALUES (3, N'Apple'), (3, N'Orange'), (3, N'Banana'), (7, N'Orange'), (7, N'Orange'), (7, N'Banana'), (9, N'Apple'), (9, N'Apple'), (9, N'Banana');
按 CustomerID 和 Product 分组计算每种产品的购买量:
SELECT CustomerID , Product , COUNT(*) as Total_bought INTO #SalesSummed FROM #Sales GROUP BY CustomerID, Product
将每个不同的产品添加到数据透视查询:
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX); SET @columns = N''; SELECT @columns += N', p.' + QUOTENAME(Product) FROM (SELECT p.Product FROM #SalesSummed AS p GROUP BY p.Product) AS x; SET @sql = N' SELECT p.CustomerID, ' + STUFF(@columns, 1, 2, '') + ' INTO #SalesMatrix FROM ( SELECT p.CustomerID, p.Product, p.Total_bought FROM #SalesSummed AS p ) AS j PIVOT ( SUM(Total_bought) FOR Product IN (' + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') + ') ) AS p;'; PRINT @sql; EXEC sp_executesql @sql;
第 3 步产生 table SalesMatrix:
CustomerID | Apple | Banana | Orange |
---|---|---|---|
3 | 1 | 1 | 1 |
7 | NULL | 1 | 2 |
9 | 2 | 1 | NULL |
这正是我们想要的(我们可以用 0 替换 NULL)!