sql - normal - Generando un histograma a partir de valores de columna en una base de datos
histograma en excel (7)
Digamos que tengo una columna de base de datos ''grado'' como esta:
|grade|
| 1|
| 2|
| 1|
| 3|
| 4|
| 5|
¿Hay una forma no trivial en SQL para generar un histograma como este?
|2,1,1,1,1,0|
donde 2 significa que el grado 1 ocurre dos veces, los 1s significan que los grados {2..5} ocurren una vez y 0 significa que el grado 6 no ocurre en absoluto.
No me importa si el histograma es una fila por conteo.
Si eso es importante, la base de datos es SQL Server a la que se accede mediante un CGI perl a través de unixODBC / FreeTDS.
EDIT: gracias por sus respuestas rápidas! Está bien si los valores no existentes (como el grado 6 en el ejemplo anterior) no ocurren, siempre que pueda distinguir qué valor del histograma pertenece a cada grado.
El uso que hace Gamecat de DISTINCT me parece un poco extraño, tendré que probarlo cuando vuelva a la oficina ...
La forma en que lo haría es similar ...
SELECT
[table].grade AS [grade],
COUNT(*) AS [occurances]
FROM
[table]
GROUP BY
[table].grade
ORDER BY
[table].grade
Para superar la falta de datos donde hay 0 ocurrencias, puede DEJAR DE UNIRSE en una tabla que contiene todas las calificaciones válidas. El COUNT (*) contará NULLS, pero COUNT (calificación) no contará los NULLS.
DECLARE @grades TABLE (
val INT
)
INSERT INTO @grades VALUES (1)
INSERT INTO @grades VALUES (2)
INSERT INTO @grades VALUES (3)
INSERT INTO @grades VALUES (4)
INSERT INTO @grades VALUES (5)
INSERT INTO @grades VALUES (6)
SELECT
[grades].val AS [grade],
COUNT([table].grade) AS [occurances]
FROM
@grades AS [grades]
LEFT JOIN
[table]
ON [table].grade = [grades].val
GROUP BY
[grades].val
ORDER BY
[grades].val
Use una tabla temporal para obtener sus valores perdidos:
CREATE TABLE #tmp(num int)
DECLARE @num int
SET @num = 0
WHILE @num < 10
BEGIN
INSERT #tmp @num
SET @num = @num + 1
END
SELECT t.num as [Grade], count(g.Grade) FROM gradeTable g
RIGHT JOIN #tmp t on g.Grade = t.num
GROUP by t.num
ORDER BY 1
SELECT COUNT(grade) FROM table GROUP BY grade ORDER BY grade
No lo he verificado, pero debería funcionar. Sin embargo, no mostrará el recuento de la calificación 6, ya que no está presente en absoluto en la tabla ...
select Grade, count(Grade)
from MyTable
group by Grade
Estoy desarrollando lo que hizo anteriormente Ilya Volodin, que debería permitirle seleccionar un rango de calificación que desea agrupar en su resultado:
DECLARE @cnt INT = 0;
WHILE @cnt < 100 -- Set max value
BEGIN
SELECT @cnt,COUNT(fe) FROM dbo.GEODATA_CB where fe >= @cnt-0.999 and fe <= @cnt+0.999 -- set tolerance
SET @cnt = @cnt + 1; -- set step
END;
De acuerdo con el artículo de Shlomo Priymak Cómo crear rápidamente un histograma en MySQL , puede usar la siguiente consulta:
SELECT grade,
COUNT(/*) AS ''Count'',
RPAD('''', COUNT(/*), ''*'') AS ''Bar''
FROM grades
GROUP BY grade
Que producirá la siguiente tabla:
grade Count Bar
1 2 **
2 1 *
3 1 *
4 1 *
5 1 *
Si hay muchos puntos de datos, también puede agrupar rangos de esta manera:
SELECT FLOOR(grade/5.00)*5 As Grade,
COUNT(*) AS [Grade Count]
FROM TableName
GROUP BY FLOOR(Grade/5.00)*5
ORDER BY 1
Además, si desea etiquetar el rango completo, puede obtener el piso y el techo antes de tiempo con un CTE.
With GradeRanges As (
SELECT FLOOR(Score/5.00)*5 As GradeFloor,
FLOOR(Score/5.00)*5 + 4 As GradeCeiling
FROM TableName
)
SELECT GradeFloor,
CONCAT(GradeFloor, '' to '', GradeCeiling) AS GradeRange,
COUNT(*) AS [Grade Count]
FROM GradeRanges
GROUP BY GradeFloor, CONCAT(GradeFloor, '' to '', GradeCeiling)
ORDER BY GradeFloor
Nota : en algunos motores SQL, puede GROUP BY
un índice de columna ordinal, pero con MS SQL, si lo desea en la instrucción SELECT
, también necesitará agruparlo, por lo tanto, copiar el rango en la expresión grupal. también.