【问题标题】:Counting values in a column separately分别计算列中的值
【发布时间】:2013-02-05 10:00:30
【问题描述】:

我的数据库中有一个具有以下结构的表。

ID   COMPANY_ID  Status
-----------------------
1       10         1 
2       10         2
3       12         2 
4       12         2 
5       12         1 
6       13         3 
7       14         3 
8       14         3 
9       10         1
10      10         2

我想将我的结果按公司 ID 分组并计算每个状态并将它们列为单独的列。

COMPANY_ID   Status 1   Status 2   Status 3
-------------------------------------------
10             2           2           0
12             1           2           0
13             0           0           1
14             0           0           2

我的问题是如何从我的表格中获得上述结果?并可能加入公司表。

尝试了几种可能,但没有得到结果。

【问题讨论】:

    标签: sql sql-server tsql pivot


    【解决方案1】:
    select  company_id
    ,       count(case when status = 1 then 1 end) as [Status 1]
    ,       count(case when status = 2 then 1 end) as [Status 2]
    ,       count(case when status = 3 then 1 end) as [Status 3]
    from    YourTable
    group by
            company_id
    

    【讨论】:

      【解决方案2】:

      这种类型的数据转换称为PIVOT。有几种方法可以透视数据。

      您可以使用带有CASE 表达式的聚合函数:

      select company_id,
        sum(case when status = 1 then 1 else 0 end) status1,
        sum(case when status = 2 then 1 else 0 end) status2,
        sum(case when status = 3 then 1 else 0 end) status3
      from yourtable
      group by company_id;
      

      SQL Fiddle with Demo

      从 SQL Server 2005+ 开始,您可以使用 PIVOT 函数:

      select company_id,
        [1] as Status1,
        [2] as Status2,
        [3] as Status3
      from
      (
        select company_id, status
        from yourtable
      )src
      pivot
      (
        count(status)
        for status in ([1], [2], [3])
      ) piv
      

      SQL Fiddle with Demo

      如果您有已知数量的值要转换为列,则上述两个版本可以很好地工作。但如果未知,则可以使用动态 SQL 生成结果:

      DECLARE @cols AS NVARCHAR(MAX),
          @query  AS NVARCHAR(MAX)
      
      select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Status'+cast(status as varchar(10))) 
                          from yourtable
                  FOR XML PATH(''), TYPE
                  ).value('.', 'NVARCHAR(MAX)') 
              ,1,1,'')
      
      set @query = 'SELECT company_id,' + @cols + ' from 
                   (
                      select company_id, ''Status''+cast(status as varchar(10)) Status
                      from yourtable
                  ) x
                  pivot 
                  (
                      count(Status)
                      for Status in (' + @cols + ')
                  ) p '
      
      execute(@query)
      

      SQL Fiddle with Demo

      全部给出结果:

      | COMPANY_ID | STATUS1 | STATUS2 | STATUS3 |
      --------------------------------------------
      |         10 |       2 |       2 |       0 |
      |         12 |       1 |       2 |       0 |
      |         13 |       0 |       0 |       1 |
      |         14 |       0 |       0 |       2 |
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-03
        • 1970-01-01
        • 2022-12-18
        • 2020-09-09
        相关资源
        最近更新 更多