Требуется количество диапазонов в sql-запросе
У меня проблема с деталями в
http://sqlfiddle.com/#!3/8e018/1
У меня есть таблица членов с отметками всех учеников.
Я пытаюсь получить счет всех студентов в диапазонах, таких как
0-9 = количество учеников 9,
10 -19 = количество учеников 0 и т.д. до 100.
Плюс, если какое-то тело может указать на хороший учебник по операторам case, будет очень хорошо
Ответы даны в порядке. но мои диапазоны фиксированы. я должен также показать 0, если нет кандидата
Это основное отличие моего вопроса. например, у меня есть также категория.
Ответы
Ответ 1
Вам не нужен оператор CASE
. Вы можете группировать результат целочисленного деления.
SELECT 10 * ( marks / 10 ) AS start_range,
10 * ( marks / 10 ) + 9 AS end_range,
count(*) AS COUNT
FROM testTable
GROUP BY marks / 10
Это приведет к группировке
0 - 9
10 - 19
/* ...*/
90 - 99
100 - 109
Если вы не хотите, чтобы 100
находился в диапазоне самостоятельно (как единственное возможное значение в конечном диапазоне), вам нужно более четко определить требования.
Чтобы включить диапазоны all, вы можете использовать
SELECT CAST(10 * ( G.Grp ) AS VARCHAR(3)) + '-'
+ CAST(10 * ( G.Grp ) + 9 AS VARCHAR(3)) AS range,
count(T.id) AS Count
FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) G(Grp)
LEFT JOIN [dbo].[testTable] T
ON G.Grp = T.marks / 10
GROUP BY G.Grp
SQL Fiddle
Ответ 2
Попробуйте что-то вроде:
SELECT CASE
WHEN marks IS NULL THEN 'Unknown'
WHEN marks <= 9 THEN '0-9'
WHEN marks <= 19 THEN '10-19'
WHEN marks <= 29 THEN '20-29'
WHEN marks <= 39 THEN '30-39'
WHEN marks <= 49 THEN '40-49'
WHEN marks <= 59 THEN '50-59'
WHEN marks <= 69 THEN '60-69'
WHEN marks <= 79 THEN '70-79'
WHEN marks <= 89 THEN '80-89'
WHEN marks <= 100 THEN '90-100'
ELSE 'Over 100'
END "Bucket",
COUNT(*) "Number of results"
FROM
testTable
GROUP BY CASE
WHEN marks IS NULL THEN 'Unknown'
WHEN marks <= 9 THEN '0-9'
WHEN marks <= 19 THEN '10-19'
WHEN marks <= 29 THEN '20-29'
WHEN marks <= 39 THEN '30-39'
WHEN marks <= 49 THEN '40-49'
WHEN marks <= 59 THEN '50-59'
WHEN marks <= 69 THEN '60-69'
WHEN marks <= 79 THEN '70-79'
WHEN marks <= 89 THEN '80-89'
WHEN marks <= 100 THEN '90-100'
ELSE 'Over 100'
END
ORDER BY
MIN(marks);
Чтобы объяснить инструкцию CASE
здесь (насколько я могу, лучше, люди могут редактировать), мне всегда нравится вводить параметр NULL, поскольку иногда он может ловить ошибки в вашем запросе. Оставшиеся WHEN
заявления должны быть понятными, и вы можете использовать их в соответствии с вашими потребностями. Имя "Bucket" - это именно то, что ваш столбец будет вызываться в конечном выпуске, поэтому вы можете изменить это, как хотите. Второй столбец должен быть агрегированным запросом, например COUNT
, чтобы оператор CASE
имел смысл.
Вы должны повторить оператор CASE
, за исключением вашего имени для него, в инструкции GROUP BY
.
Ответ 3
Если вам нужны и пустые диапазоны (предположим), попробуйте это:
;WITH Ranges
AS
(
SELECT 0 n
UNION ALL
SELECT n + 1 FROM Ranges
WHERE n < 9
)
SELECT CAST((n*10) as VARCHAR) + ' - ' + CAST((n*10 + 9) as VARCHAR) [Range], COUNT(marks) Cnt FROM Ranges
LEFT JOIN [testTable] T
ON marks >= (n*10) AND marks <= (n*10 + 9)
GROUP BY n*10, n*10 + 9
SQL FIDDLE DEMO