Генерация гистограммы из значений столбцов в базе данных - PullRequest
19 голосов
/ 28 января 2009

Допустим, у меня есть столбец базы данных 'оценка', например:

|grade|
|    1|
|    2|
|    1|
|    3|
|    4|
|    5|

Есть ли в SQL нетривиальный способ генерации гистограммы, подобной этой?

|2,1,1,1,1,0|

, где 2 означает, что оценка 1 встречается дважды, средние оценки 1s {2..5} встречаются один раз, а 0 означает, что оценка 6 вообще не встречается.

Я не против, если гистограмма - одна строка на счет.

Если это имеет значение, база данных - это SQL Server, доступ к которому осуществляется через Perl CGI через unixODBC / FreeTDS.

РЕДАКТИРОВАТЬ: Спасибо за ваши быстрые ответы! Это нормально, если несуществующие значения (например, оценка 6 в приведенном выше примере) не встречаются, пока я могу определить, какое значение гистограммы принадлежит какому классу.

Ответы [ 7 ]

29 голосов
/ 28 января 2009
SELECT COUNT(grade) FROM table GROUP BY grade ORDER BY grade

Не проверено, но оно должно работать. Однако не будет показывать счет для оценки 6s, поскольку его нет в таблице вообще ...

6 голосов
/ 28 января 2009

Используйте временную таблицу, чтобы получить пропущенные значения:

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
4 голосов
/ 22 декабря 2016

Если точек данных много, вы также можете сгруппировать диапазоны вместе следующим образом:

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, вам нужно сгруппировать этим также, следовательно, копируя Range в Выражение группы.

Вариант 2 : Вы можете использовать операторы case для выборочного подсчета значений в произвольные ячейки, а затем отключить их , чтобы получить ряд за числом включенных значений

3 голосов
/ 28 января 2009

Использование GameCat DISTINCT мне кажется немного странным, придется попробовать его, когда я вернусь в офис ...

Хотя я бы сделал это похоже ...

SELECT
    [table].grade        AS [grade],
    COUNT(*)             AS [occurances]
FROM
    [table]
GROUP BY
    [table].grade
ORDER BY
    [table].grade

Чтобы преодолеть недостаток данных при наличии 0 различий, вы можете ВЕРНУТЬСЯ В СООТВЕТСТВИЕ к таблице, содержащей все действительные оценки. 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
2 голосов
/ 07 сентября 2014

Согласно статье Шломо Приймака Как быстро создать гистограмму в 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       *
2 голосов
/ 28 января 2009
select Grade, count(Grade)
from MyTable
group by Grade
0 голосов
/ 30 августа 2015

Я строю на том, что Илья Володин делал выше, это должно позволить вам выбрать диапазон оценок, которые вы хотите сгруппировать в своем результате:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...