SQL 服务器数据透视查询 - 问题
SQL Server pivot query - questions
我有一个包含 3 列的 table:order_id, product_id, product_count
第一列是客户传递的订单,第二列是产品唯一id,第三列是订单中购买的产品数量。
我想创建一个 order_id
/ product_id
的矩阵,其中包含购买的商品数量。
因此我想要这样的东西:
如果我提出这个要求:
SELECT *
FROM
(SELECT
[order_id], [prod_id], [product_count]
FROM mydb.dbo.mytable) QueryResults
PIVOT
(SUM([product_count])
FOR [prod_id] IN ([21], [22], [23])
) AS PivotTable
我的问题是我有 200 多种不同的产品要检索。有没有办法不用输入所有值就可以做到?
我写了这篇文章,并且在 BICube 发表他的评论时正在测试 - 是的,这是另一个动态 Pivot。您已经有了基本代码 - 您需要做的就是
- 使用列名列表构建一个变量,例如
ColList = '[21],[22],[23]'
- 在 PIVOT 中使用此变量来提供列列表 - 但请注意,您随后需要将整个语句设为 Dynamic SQL。
这是我写的答案(注意我只是编造订单数据而不是从你的图片中转录)。
CREATE TABLE #MyTable (Order_ID int, Prod_ID int, Product_Count int);
INSERT INTO #MyTable (Order_ID, Prod_ID, Product_Count)
VALUES
(100, 1, 15),
(100, 2, 12),
(100, 5, 17),
(101, 3, 10),
(101, 4, 11),
(102, 6, 12),
(102, 1, 16);
SELECT * FROM #MyTable;
DECLARE @ColList nvarchar(max) = N''
SELECT @ColList += N',' + QUOTENAME(LTRIM(STR(Prod_ID)))
FROM (SELECT DISTINCT Prod_ID FROM #MyTable) A;
SET @ColList = STUFF(@ColList,1,1,''); -- Remove leading comma
DECLARE @PivotSQL nvarchar(max);
SET @PivotSQL =
N'SELECT * FROM (
SELECT
[Order_ID],
[prod_id],
[product_count]
FROM #MyTable
) QueryResults
PIVOT (
SUM([product_count])
FOR [prod_id]
IN (' + @ColList + N')
) AS PivotTable;'
EXEC (@PivotSQL);
这是结果
Order_ID 1 2 3 4 5 6
100 15 12 NULL NULL 17 NULL
101 NULL NULL 10 11 NULL NULL
102 16 NULL NULL NULL NULL 12
根据@seanb 救了我的答案,我尝试用0替换NULL值。我明白了原理(基础)。以下是我如何更新 SQL 请求以替换 NULL 值。
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX),
@PivotColumnNames AS NVARCHAR(MAX),
@PivotSelectColumnNames AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT @PivotColumnNames= ISNULL(@PivotColumnNames + ',','') + QUOTENAME(prod_id)
FROM (SELECT DISTINCT prod_id FROM #MyTable) AS prod_id
--Get distinct values of the PIVOT Column with isnull
SELECT @PivotSelectColumnNames
= ISNULL(@PivotSelectColumnNames + ',','')
+ 'ISNULL(' + QUOTENAME(prod_id) + ', 0) AS '
+ QUOTENAME(prod_id)
FROM (SELECT DISTINCT prod_id FROM #MyTable) AS prod_id
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'SELECT order_id, ' + @PivotSelectColumnNames + '
FROM #MyTable
PIVOT(SUM(product_count)
FOR prod_id IN (' + @PivotColumnNames + ')) AS PivotTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery
我有一个包含 3 列的 table:order_id, product_id, product_count
第一列是客户传递的订单,第二列是产品唯一id,第三列是订单中购买的产品数量。
我想创建一个 order_id
/ product_id
的矩阵,其中包含购买的商品数量。
因此我想要这样的东西:
如果我提出这个要求:
SELECT *
FROM
(SELECT
[order_id], [prod_id], [product_count]
FROM mydb.dbo.mytable) QueryResults
PIVOT
(SUM([product_count])
FOR [prod_id] IN ([21], [22], [23])
) AS PivotTable
我的问题是我有 200 多种不同的产品要检索。有没有办法不用输入所有值就可以做到?
我写了这篇文章,并且在 BICube 发表他的评论时正在测试 - 是的,这是另一个动态 Pivot。您已经有了基本代码 - 您需要做的就是
- 使用列名列表构建一个变量,例如
ColList = '[21],[22],[23]'
- 在 PIVOT 中使用此变量来提供列列表 - 但请注意,您随后需要将整个语句设为 Dynamic SQL。
这是我写的答案(注意我只是编造订单数据而不是从你的图片中转录)。
CREATE TABLE #MyTable (Order_ID int, Prod_ID int, Product_Count int);
INSERT INTO #MyTable (Order_ID, Prod_ID, Product_Count)
VALUES
(100, 1, 15),
(100, 2, 12),
(100, 5, 17),
(101, 3, 10),
(101, 4, 11),
(102, 6, 12),
(102, 1, 16);
SELECT * FROM #MyTable;
DECLARE @ColList nvarchar(max) = N''
SELECT @ColList += N',' + QUOTENAME(LTRIM(STR(Prod_ID)))
FROM (SELECT DISTINCT Prod_ID FROM #MyTable) A;
SET @ColList = STUFF(@ColList,1,1,''); -- Remove leading comma
DECLARE @PivotSQL nvarchar(max);
SET @PivotSQL =
N'SELECT * FROM (
SELECT
[Order_ID],
[prod_id],
[product_count]
FROM #MyTable
) QueryResults
PIVOT (
SUM([product_count])
FOR [prod_id]
IN (' + @ColList + N')
) AS PivotTable;'
EXEC (@PivotSQL);
这是结果
Order_ID 1 2 3 4 5 6
100 15 12 NULL NULL 17 NULL
101 NULL NULL 10 11 NULL NULL
102 16 NULL NULL NULL NULL 12
根据@seanb 救了我的答案,我尝试用0替换NULL值。我明白了原理(基础)。以下是我如何更新 SQL 请求以替换 NULL 值。
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX),
@PivotColumnNames AS NVARCHAR(MAX),
@PivotSelectColumnNames AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT @PivotColumnNames= ISNULL(@PivotColumnNames + ',','') + QUOTENAME(prod_id)
FROM (SELECT DISTINCT prod_id FROM #MyTable) AS prod_id
--Get distinct values of the PIVOT Column with isnull
SELECT @PivotSelectColumnNames
= ISNULL(@PivotSelectColumnNames + ',','')
+ 'ISNULL(' + QUOTENAME(prod_id) + ', 0) AS '
+ QUOTENAME(prod_id)
FROM (SELECT DISTINCT prod_id FROM #MyTable) AS prod_id
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'SELECT order_id, ' + @PivotSelectColumnNames + '
FROM #MyTable
PIVOT(SUM(product_count)
FOR prod_id IN (' + @PivotColumnNames + ')) AS PivotTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery