I'm trying to figure out how to write a query that counts values across multiple columns, with the result table having a count in each column for every possible value of any column.
Example: Say I have mytable
Source data table:
P1 P2 P3
-----------
a b a
a a a
b b b
a b b
I want a query that counts a's and b's in each column, producing something like:
Desired query output:
P1 P2 P3
-------------
a | 3 1 2
b | 1 3 2
I know I can do this for a single column easily with a group by:
select P1, count(*) as mycounts
from mytable
group by P1
But is it possible to do this for every column?
I'm using SQL Server 2008 (T-SQL). Thanks in advance for any help!
Maybe something like this:
First some test data:
DECLARE @tbl TABLE(P1 VARCHAR,P2 VARCHAR,P3 VARCHAR)
INSERT INTO @tbl
SELECT 'a','b','a' UNION ALL
SELECT 'a','a','a' UNION ALL
SELECT 'b','b','b' UNION ALL
SELECT 'a','b','b'
Then a pivot like this:
SELECT
*
FROM
(
SELECT 'P1' AS P, P1 AS PValue,P1 AS test FROM @tbl
UNION ALL
SELECT 'P2',P2,P2 FROM @tbl
UNION ALL
SELECT 'P3',P3,P3 FROM @tbl
) AS p
PIVOT
(
COUNT(PValue)
FOR P IN ([P1],[P2],[P3])
) AS pvt
Here is more information about pivot and unpivot
Probably not the most efficient but this works.
;WITH data
AS
(
SELECT 'a' AS p1, 'b' AS p2, 'a' AS p3
UNION ALL
SELECT 'a', 'a','a'
UNION ALL
SELECT 'b','b','b'
UNION ALL
SELECT 'a','b','b'
)
SELECT
p_one.value AS header,
p1,
p2,
p3
FROM (SELECT
p1 AS value,
count(*) AS p1
FROM data d
GROUP BY p1) p_one
left JOIN (SELECT
p2 AS value,
count(*) AS p2
FROM data d
GROUP BY p2) p_two
ON p_two.value = p_one.value
left JOIN (SELECT
p3 AS value,
count(*) AS p3
FROM data d
GROUP BY p3) p_three
ON p_two.value = p_three.value