#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть запрос
select count(distinct(a.studentid)count,
case
when a.Age <=19 then '1-19'
when a.Age between 20 and 29 then '20-29'
end as age_range
from table a
where 0 = 0
group by a.age
Результат
count age_range
10 1-19
5 1-19
12 20-29
18 20-29
Не уверен, почему не группировать по диапазону и ожидать результатов. Спасибо.
count age_range
15 1-19
30 20-29
Комментарии:
1. Причиной неожиданного результата является то, что
case
выражение было применено после группировки. По-видимому, у вас есть четыре разных возраста в этих данных, таким образом, четыре выходных строки.
Ответ №1:
Я бы предложил cross apply
определить псевдоним:
select v.age_range, count(distinct a.studentid)count,
from table a cross apply
(values (case when a.Age <= 19 then 'Under 12 months-19'
when a.Age between 20 and 29 then '20-29'
end)
) as v(age_range)
group by v.age_range;
SQL Server не допускает псевдонимы в качестве GROUP BY
ключей. Я думаю, что определение псевдонима в FROM
предложении является самым простым методом; вы также можете использовать CTE или подзапрос или повторить case
выражение.
Я должен также отметить, что between
для case
. Предложения оцениваются по порядку, чтобы вы могли использовать:
(case when a.Age <= 19 then 'Under 12 months-19'
when a.Age <= 29 then '20-29'
end)
Ответ №2:
Группируйте по вашему заявлению case:
select count(distinct(a.studentid)count,
case
when a.Age <=19 then 'Under 12 months-19'
when a.Age between 20 and 29 then '20-29'
end as age_range
from table a
where 0 = 0
group by case
when a.Age <=19 then 'Under 12 months-19'
when a.Age between 20 and 29 then '20-29'
end
ИЛИ просто:
select count(distinct(a.studentid)count,
case
when a.Age <=19 then 'Under 12 months-19'
when a.Age between 20 and 29 then '20-29'
end as age_range
from table a
where 0 = 0
group by 2
Ответ №3:
Я предпочитаю хранить УРОВНИ в обобщенной таблице уровней, таким образом удаляя логику из кода и позволяя вам использовать несколько основных серверов.
Пример
Declare @Tier table (Tier_Grp varchar(50),Tier_R1 money,Tier_R2 money,Tier_Title varchar(50))
Insert Into @Tier values
('Age Range',1 , 20,' 1-19')
,('Age Range',21, 29,'21-29')
,('Age Range',31, 39,'31-39')
,('Age Range',40,999,'Over 40')
,('Age Range',1 ,999,'Total')
Select A.Tier_R1
,A.Tier_R2
,A.Tier_Title
,Cnt = count(Distinct studentid)
From @Tier A
Left Join YourTable B
on A.Tier_Grp='Age Range'
and B.Age>=A.Tier_R1
and B.Age<A.Tier_R2
Group By A.Tier_R1
,A.Tier_R2
,A.Tier_R2
Order By Tier_R1,Tier_R2