【问题标题】:Write a SQL statement as a pivot table?将 SQL 语句编写为数据透视表?
【发布时间】:2022-11-10 01:56:03
【问题描述】:

在 SQL Server 中,假设您有一个这样的表,称为“测试”:

Owner State
John Pending
John Complete
Sue Required
Sue Required
Sue Complete
Frank Complete

我希望枢轴数据显示如下:

Owner Required Pending Complete
John 0 1 1
Sue 2 0 1
Frank 0 0 1

你如何编写 SQL 语句来产生它?似乎 PIVOT 表会派上用场,但只是不确定如何将其包含在语句中。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    您可以使用以下数据透视查询:

    SELECT
        Owner,
        COUNT(CASE WHEN Genre = 'Required' THEN 1 END) AS Required,
        COUNT(CASE WHEN Genre = 'Pending'  THEN 1 END) AS Pending,
        COUNT(CASE WHEN Genre = 'Complete' THEN 1 END) AS Complete
    FROM Testing
    GROUP BY Owner;
    

    【讨论】:

    • 我将类型字段更改为“状态”,但这并不是什么大不了的事。我的下一个问题是如果添加新状态会怎样。如果可能的话,我不想硬编码这些值。
    • 在这种情况下,您需要动态 SQL。
    • 希望我可以将两者都标记为答案。如果值是已知的,这也很有效。谢谢你的领导:)
    • @slashbrackets您做出了正确的决定。
    【解决方案2】:

    Tim 提供的条件聚合 (+1) 提供了更多的灵活性,并且通常会有性能提升

    也就是说,这是一个 PIVOT 选项

    示例或dbFiddle

    Select * 
     From  YourTable
     Pivot ( count([State]) for [State] in  ([Required],[Pending],[Complete]) ) pct
    

    结果

    笔记:如果您的表的列多于显示的列,则需要一个子查询来限制必不可少的列。

    这是一个动态版本

    Declare @SQL varchar(max) = '
    Select *
     From ( Select [State] 
                  ,[Owner] 
             From  YourTable ) src
     Pivot (count([State]) For [State] in (' + Stuff((Select Distinct ','+QuoteName([State]) 
                                                        From YourTable A 
                                                        Order By 1 Desc 
                                                        For XML Path('')),1,1,'')  + ') ) p
    Order By Owner'
    --Print @SQL
    Exec(@SQL)
    

    【讨论】:

    • 我尝试在 IN 之后使用子查询,例如:..... IN (SELECT DISTINCT [State] FROM [Testing]) 但它抱怨子查询的 SELECT 语句有错误。任何线索如何做到这一点?
    • @slashbrackets Nope :) SQL Server 在设计上是声明性的,不支持宏替换。那将需要动态 SQL。许多可用的示例
    • @slashbrackets 添加了动态版本。假设 string_agg() 不可用,使用了 stuff/xml 方法。
    • 动态 sql 返回所有列和所有行,就像正常的“从 YourTable 中选择 *”一样......甚至与我刚刚那样的确切行数相同。
    • @slashbrackets 正如我在注释中提到的那样:如果您的实际表有更多列,则需要一个子查询来“馈送”只需要的列
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    相关资源
    最近更新 更多