Ответ 1
SELECT COUNT(grade) FROM table GROUP BY grade ORDER BY grade
Не проверял его, но он должен работать. Однако он не будет показывать количество баллов для класса 6s, поскольку он вообще не присутствует в таблице...
Скажем, у меня есть столбец базы данных 'grade' следующим образом:
|grade|
| 1|
| 2|
| 1|
| 3|
| 4|
| 5|
Существует ли нетривиальный способ в SQL генерировать такую гистограмму?
|2,1,1,1,1,0|
где 2 означает, что класс 1 встречается дважды, средние оценки {2..5} 1s происходят один раз, а 0 означает, что оценка 6 вообще не встречается.
Я не возражаю, если гистограмма - одна строка за счет.
Если это имеет значение, база данных - это SQL Server, доступ к которой осуществляется через Perl CGI через unixODBC/FreeTDS.
EDIT: Спасибо за ваши быстрые ответы! Это нормально, если несуществующие значения (например, класс 6 в приведенном выше примере) не возникают, если я могу определить, какое значение гистограммы принадлежит какому классу.
SELECT COUNT(grade) FROM table GROUP BY grade ORDER BY grade
Не проверял его, но он должен работать. Однако он не будет показывать количество баллов для класса 6s, поскольку он вообще не присутствует в таблице...
Используйте временную таблицу для получения ваших отсутствующих значений:
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
Использование Gamecat DISTINCT кажется немного странным для меня, придется попробовать его, когда я вернусь в офис...
То, как я это сделаю, похоже, хотя...
SELECT
[table].grade AS [grade],
COUNT(*) AS [occurances]
FROM
[table]
GROUP BY
[table].grade
ORDER BY
[table].grade
Чтобы преодолеть нехватку данных, где есть 0 событий, вы можете ВСПОМОГАТЬ JOIN на таблицу, содержащую все допустимые оценки. COUNT (*) будет считать NULLS, но COUNT (класс) не будет считать 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
select Grade, count(Grade)
from MyTable
group by Grade
Согласно статье Шломо Приймака Как быстро создать гистограмму в MySQL, вы можете использовать следующий запрос:
SELECT grade,
COUNT(\*) AS 'Count',
RPAD('', COUNT(\*), '*') AS 'Bar'
FROM grades
GROUP BY grade
Будет выведена следующая таблица:
grade Count Bar
1 2 **
2 1 *
3 1 *
4 1 *
5 1 *
Если есть много точек данных, вы также можете группировать группы следующим образом:
SELECT FLOOR(grade/5.00)*5 As Grade,
COUNT(*) AS [Grade Count]
FROM TableName
GROUP BY FLOOR(Grade/5.00)*5
ORDER BY 1
Кроме того, если вы хотите обозначить весь диапазон, вы можете получить пол и потолок заблаговременно с помощью 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
Примечание. В некоторых SQL-машинах вы можете GROUP BY
указать индекс исходной колонки, но с MS SQL, если вы хотите, чтобы это было в инструкции SELECT
, вам понадобится Кроме того, группа также копирует диапазон в выражение группы.
Я основываюсь на том, что сделал Илья Володин выше, что должно позволить вам выбрать диапазон оценки, который вы хотите группировать вместе в своем результате:
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;