【问题标题】:SQL Data range using Case使用大小写的 SQL 数据范围
【发布时间】:2020-06-15 23:38:34
【问题描述】:

我有 table1 的数据

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+

感谢您的帮助。

【问题讨论】:

    标签: sql sql-server group-by count left-join


    【解决方案1】:

    你可以用row_constructorvalues()枚举范围,然后用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
    

    【讨论】:

    • 感谢您的帮助
    【解决方案2】:

    此类问题的关键是要认识到 SQL 查询本身不能真正创建行,它只能返回传递给它的数据的过滤/透视/分组子集。我们需要将其转换为基于 SET 的查询,而不是使用 CASE 语句,其中您的案例选项表示为表中的行。

    对于较大的集合,您可以使用递归查询来构建选项,或者您可以构建临时表或表变量来存储行。然而,SQL Server 2008 引入了Table Value Constructor,可用于快速创建内联表变量以供您的查询使用,Pinal Dave has a simple writeup on this

    -- 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+
    

    【讨论】:

      猜你喜欢
      • 2012-05-12
      • 2015-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-24
      相关资源
      最近更新 更多