sql数据范围用例

ohfgkhjo  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(249)

我有数据表1

Age
10
21
35
50

还有我的问题

select count(*) as Total, *
from 

( 
select
case

 when age <18 then '0-20'
 when age between 20 and 29 then '20-29'
 when age between 30 and 39 then '30-39'
 when age between 40 and 49 then '40-49'
 when age between 50 and 59 then '50-59'
 when age between 30 and 39 then '30-39'
 when age between 60 and 99 then '60+'
 end as age_range
 from table1
 ) t
 group by t.age_range

结果呢

Total   age_range
1       0-20
1       20-29
1       30-39
1       50-59

我希望如何看到这样的结果(缺少40-49计数0和60以上+计数0)

Total   age_range
1        0-20
1        20-29
1        30-39
0        40-49
1        50-59
0        60+

谢谢你的帮助。

zaq34kh6

zaq34kh61#

您可以使用行构造函数枚举范围 values() ,然后把table拿过来 left join ,最后聚合:

select count(t.age) total, r.age_range
from (values 
    ( '0-19',  0, 19),
    ('20-29', 20, 29),
    ('30-39', 30, 39),
    ('40-49', 40, 49),
    ('50-59', 50, 59),
    (  '60+', 60, 99),
) r(age_range, low, high)
left join table1 t
    on t.age between r.low and r.high
group by r.age_range
yrwegjxp

yrwegjxp2#

解决这类问题的关键是要认识到sql查询本身不能真正创建行,它只能返回传递给它的经过筛选/透视/分组的数据子集。而不是使用 CASE 语句,我们需要将其转换为一个基于集合的查询,在该查询中,case选项被表示为表中的行。
对于较大的集合,可以使用递归查询来构建选项,也可以构造临时表或表变量来存储行。不过,SQLServer2008引入了表值构造函数,可用于快速创建内联表变量以在查询中使用,PinalDave对此有一个简单的writeup

-- Existing data
DECLARE @table AS Table(
    age INT
)
INSERT INTO @table (age)
VALUES (10),(21),(35),(50)

-- updated query
select count(age) as Total, AgeRange
from @table t
RIGHT OUTER JOIN (values 
    ( 0,19, '0-19'),
    ( 20, 29, '20-29'),
    ( 30, 39, '30-39'),
    ( 40, 49, '40-49'),
    ( 50, 59, '50-59'),
    ( 60, 999, '60+')
) options(min, max, AgeRange) on t.age BETWEEN options.min AND options.max
GROUP BY AgeRange

结果:

Total       AgeRange
----------- --------
1           0-19
1           20-29
1           30-39
0           40-49
1           50-59
0           60+

相关问题