I have a table in my database with the following structure.
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
I want to group my results on company ID and count each status and list them as separate columns.
i.e.
COMPANY_ID Status 1 Status 2 Status 3
-------------------------------------------
10 2 2 0
12 1 2 0
13 0 0 1
14 0 0 2
My question is how do I get the results above from my table? and probably join in with the company table.
Tried several possibilities, but didn't get the results.
This type of data transformation is known as a PIVOT
. There are several ways that you are pivot the data.
You can use an aggregate function with a CASE
expression:
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;
See SQL Fiddle with Demo
Starting in SQL Server 2005+ you can use the PIVOT
function:
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
See SQL Fiddle with Demo.
The two versions above work well if you have a known number of values to transform into columns. But if it is unknown, then you can use dynamic SQL to generate the result:
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)
See SQL Fiddle with Demo.
All give the result:
| COMPANY_ID | STATUS1 | STATUS2 | STATUS3 |
--------------------------------------------
| 10 | 2 | 2 | 0 |
| 12 | 1 | 2 | 0 |
| 13 | 0 | 0 | 1 |
| 14 | 0 | 0 | 2 |
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