Grupo SQL por / recuento: ¿contar los mismos valores en varias columnas?

Intento averiguar cómo escribir una consulta que cuente los valores en varias columnas, y la tabla de resultados cuente en cada columna para cada valor posible de cualquier columna.

Ejemplo: decir que tengo mytable

Source data table: P1 P2 P3 ----------- aba aaa bbb abb 

Quiero una consulta que cuente las letras a y b en cada columna, produciendo algo como:

 Desinetworking query output: P1 P2 P3 ------------- a | 3 1 2 b | 1 3 2 

Sé que puedo hacer esto para una sola columna fácilmente con un grupo :

 select P1, count(*) as mycounts from mytable group by P1 

Pero, ¿es posible hacer esto para cada columna?

Estoy usando SQL Server 2008 (T-SQL). ¡Gracias de antemano por cualquier ayuda!

Tal vez algo como esto:

Primero algunos datos de testing:

 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' 

Entonces un pivote como este:

 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 

Aquí hay más información sobre pivote y unpivot

Probablemente no sea el más eficiente, pero esto funciona.

  ;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