【问题标题】:SQL Creating a stored proc for returning age bandsSQL 创建用于返回年龄段的存储过程
【发布时间】:2009-05-12 10:15:41
【问题描述】:

我有一个名为 Person 的表,其中包含一个名为 PersonAge 的字段。我需要按年龄段(即“12 岁及以下”、“13-17 岁”、“18-25 岁”、“25 岁及以上”)对年龄进行分组,并使用存储过程返回此结果集。

理想情况下,我需要返回 2 个字段,'Age Band','Total' 像这样

年龄段总计
12 岁及以下 5
13 - 17 8
18 - 25 7
25 岁及以上 10

【问题讨论】:

  • @Mich,您的“18-25”和“25 及以上”年龄段重叠。
  • @Lieven 发现了 Lieven,这是一个错字,因为它是深夜(这是我的借口!),我可以向你保证它不在生产代码中......

标签: sql stored-procedures


【解决方案1】:

创建一个包含您的乐队的表格:

CREATE TABLE agebands
(
    id INT NOT NULL PRIMARY KEY,
    lower_bound INT NOT NULL,
    upper_bound INT NOT NULL
)
CREATE INDEX IDX_agebands_bounds ON (lower_bound, upper_bound)

然后用你的数据填充它:

INSERT INTO agebands VALUES (1, 0, 12)
INSERT INTO agebands VALUES (2, 13, 17)
INSERT INTO agebands VALUES (3, 18, 24)
INSERT INTO agebands VALUES (4, 25, 199)

然后加入它:

SELECT
    lower_bound, upper_bound,
    COUNT(*) AS number_of_people
FROM
    persons
    INNER JOIN agebands
        ON person_age BETWEEN lower_bound AND upper_bound
GROUP BY
    lower_bound, upper_bound
ORDER BY
    lower_bound

这样可以灵活地调整频段。当然,这里使用 UNION 的另一个答案也是可用的,如果您可以/不会将另一个表添加到数据库中,这更合适。

【讨论】:

  • +1 整洁,尽管对于这个简单的例子,我认为联合比额外的表更容易维护。一年后,没有人记得他们所要做的就是添加、删除或更改表中的记录,而无需阅读源程序。
  • +1 这比基于联合的答案更有效和可维护
  • 这完全取决于使用情况。如果 hit 是一种常用的分组功能,按年龄段分组,并且这些年龄段是相同的,我会说添加表单来操作这样的表格是用户友好的方式,而不是必须确保执行 SQL 的代码每次都构建正确的 SQL。但是,是的,如果这是一次性或就地类型的功能,我也会选择联合。
  • Lievens UNION answer 和 lassevks extra table 方法之间非常接近。我最终选择了 lassevks 额外表格方法,因为它具有额外的灵活性,允许客户更改自己的年龄段。非常感谢您的出色意见...
  • 这完美解决了我的问题!从来没有想过使用连接——我涉及到一个复杂的 CTE。我想使用存储在另一个表中的可变年龄段,所以 CASE 对我不起作用。谢谢。
【解决方案2】:

一个简单的 UNION 就足够了。

SELECT [Ageband] = '12 and under', COUNT(*)
FROM dbo.Person
WHERE PersonAge <= 12
UNION ALL SELECT '13-17', COUNT(*)
FROM dbo.Person
WHERE PersonAge BETWEEN 13 AND 17
UNION ALL SELECT '18-25', COUNT(*)
FROM dbo.Person
WHERE PersonAge BETWEEN 18 AND 25
UNION ALL SELECT '26 and over', COUNT(*)
FROM dbo.Person
WHERE PersonAge >= 26

【讨论】:

    【解决方案3】:

    以下应该给出:

    select count(*), person_age
    from (
        select (case 
                   when age between 0 and 12 then '12 and under'
                   when age between 13 and 17 then '13-17'
                   when age between 18 and 25 then '18-15'
                   else 'Above 25'
                end) as 'person_age'
        from person)
    group by person_age
    

    【讨论】:

      【解决方案4】:

      在 SQL 中,您不能按列别名进行分组。您需要像这样重复 case 语句。

      select count(*), 
      case  
          when aged between 0 and 12 then '12 and under'
          when aged between 13 and 17 then '13-17'
          when aged between 18 and 25 then '18-15'
          else 'Above 25' end
      from person
      group by 
      case  
          when aged between 0 and 12 then '12 and under'
          when aged between 13 and 17 then '13-17'
          when aged between 18 and 25 then '18-15'
          else 'Above 25'
      end
      

      【讨论】:

        【解决方案5】:
        declare @tempT table(age int)
        declare @temp2 table(age2 varchar(15))
        
        insert into @tempT(age) values(1)
        insert into @tempT(age) values(2)
        insert into @tempT(age) values(3)
        insert into @tempT(age) values(4)
        insert into @tempT(age) values(5)
        insert into @tempT(age) values(6)
        insert into @tempT(age) values(7)
        insert into @tempT(age) values(8)
        insert into @tempT(age) values(9)
        insert into @tempT(age) values(10)
        insert into @tempT(age) values(11)
        
        insert into @Temp2
        select  case  
        when age < 3 then '<3'
        when age >= 3 and age < 5 then '>= 3 and < 5'
        when age >= 5 then '>=5'
        end
        from @tempT
        
        select count(*), age2 from @Temp2 
        GROUP BY age2
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-17
          • 2020-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多