分别计算列中的值

时间:2013-02-20 11:53:12

标签: sql sql-server tsql pivot

我的数据库中有一个表格,结构如下。

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

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

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

2 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:4)

此类数据转换称为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 |