SQL Server 数据透视查询 - 问题

Posted

技术标签:

【中文标题】SQL Server 数据透视查询 - 问题【英文标题】:SQL Server pivot query - questions 【发布时间】:2020-11-21 23:52:25 【问题描述】:

我有一个包含 3 列的表格: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 多种不同的产品。有没有办法在不输入所有值的情况下做到这一点?

【问题讨论】:

这能回答你的问题吗? SQL Server dynamic PIVOT query? 【参考方案1】:

当 BICube 发布他的评论时,我已经写了这个并且正在测试 - 是的,这是另一个动态 Pivot。你有基本的代码 - 你需要做的就是

使用列名列表构建变量,例如ColList = '[21],[22],[23]' 在 PIVOT 中使用此变量来提供列列表 - 但请注意,您需要将整个语句变成动态 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

【讨论】:

【参考方案2】:

基于拯救了我的@seanb 答案,我尝试将 NULL 值替换为 0。我理解了原理(基础)。这是我更新 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

【讨论】:

以上是关于SQL Server 数据透视查询 - 问题的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 数据透视查询 - 问题

SQL Server 中的数据透视表查询

没有聚合函数的 SQL Server 数据透视查询

SQL Server 查询侧重于“透视”包含非数字数据的表

Microsoft Access 数据透视表到 SQL Server 数据透视表

列子句中带有子查询的 MS SQL Server 数据透视表