【问题标题】:SQL Group by Age Range按年龄范围划分的 SQL 组
【发布时间】:2012-02-04 11:32:06
【问题描述】:

SQL 2005, 我有一个包含“ages_c”列的表,我需要按年龄范围对记录进行分组。 这是我在这个网站上找到的查询,它让我 90% 在那里,但“分组依据”出错,*无效的列名 'age_range'*

 select 
  case
   when age_c <18 then 'Under 18'
   when age_c between 18 and 24 then '18-24'
   when age_c between 25 and 34then '25-34'
 END as age_range, 
 Count(*) as count
 from contacts
 group by age_range
 order by age_range

当我按“age_c”分组和排序时,我的结果是:

  Under 18  1
  18-24 1
  18-24 1
  25-34 1

我想要的是:

 Under 18   1
  18-24 2      
  25-34 1

谢谢。

【问题讨论】:

    标签: sql sql-server sql-server-2005 group-by


    【解决方案1】:
    CASE WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 20 AND 29 THEN '20-29'
    
            WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 30 AND 39 THEN '30-39'
    
            WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 40 AND 49 THEN '40-49'
    
               WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 50 AND 59 THEN '50-59'
    
    
            ELSE '60 AND Older'
    
        END AS age_group_Frequency,
    
    count (CASE WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 20 AND 29 THEN '20-29'
    
            WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 30 AND 39 THEN '30-39'
    
            WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 40 AND 49 THEN '40-49'
    
               WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 50 AND 59 THEN '50-59'
    
    
            ELSE '60 AND Older'
    
        END) AS age_group
           
         
    
    
      FROM
    
    put your statement****
    
    where
    
    *****
    
      group by 
    CASE WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 20 AND 29 THEN '20-29'
    
            WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 30 AND 39 THEN '30-39'
    
            WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 40 AND 49 THEN '40-49'
    
               WHEN DATEDIFF(YEAR, DateOfBirth, GETDATE()) BETWEEN 50 AND 59 THEN '50-59'
    
    
            ELSE '60 AND Older'
    
        END
    

    【讨论】:

      【解决方案2】:

      如果您的数据库支持 FILTER WHERE 语法,那么这可以以非常优雅的方式归档:

      SELECT COUNT(id) FILTER (WHERE (age < 18)) AS "Under 18",
             COUNT(id) FILTER (WHERE (age >= 18 AND age <= 24)) AS "18-24",
             COUNT(id) FILTER (WHERE (age >= 25 AND age <= 34)) AS "25-34"
      FROM contacts
      

      如果没有,或者这个:

      SELECT count(CASE WHEN (age < 18) THEN id ELSE null END)                AS "Under_18",
             count(CASE WHEN (age >= 18 AND age <= 24) THEN id ELSE null END) AS "18-24",
             count(CASE WHEN (age >= 25 AND age <= 34) THEN id ELSE null END) AS "25-34"
      FROM contacts
      

      【讨论】:

        【解决方案3】:

        试试这个方法:

         SELECT SUM(CASE WHEN age_c < 18 THEN 1 ELSE 0 END) AS [Under 18],
                SUM(CASE WHEN age_c BETWEEN 18 AND 24 THEN 1 ELSE 0 END) AS [18-24],
                SUM(CASE WHEN age_c BETWEEN 25 AND 34 THEN 1 ELSE 0 END) AS [25-34]
         FROM contacts
        

        【讨论】:

        • 谢谢乔...我很欣赏它的简单性。
        【解决方案4】:

        您不能按在查询中创建的列进行分组。你必须这样做:

        SELECT count(*), * FROM 
        (
        select 
          case
           when age_c <18 then 'Under 18'
           when age_c between 18 and 24 then '18-24'
           when age_c between 25 and 34then '25-34'
         END as age_range 
         from contacts
        ) t
        group by age_range
        order by age_range
        

        或分组方式

        case
               when age_c <18 then 'Under 18'
               when age_c between 18 and 24 then '18-24'
               when age_c between 25 and 34then '25-34'
        END
        

        【讨论】:

        • 我更喜欢临时表而不是嵌套查询,因为它使查询看起来更干净,但它实际上是同一枚硬币的两个方面。
        • 感谢 Mithrandir。这是非常接近的,我不得不重新安排它来让它工作......但它确实可以工作。
        【解决方案5】:

        这是您使用的实际代码吗?它看起来不像,因为您在 34 和 then 之间缺少一个空格。该代码会在 SQL 中出错。介意分享实际未修改的查询吗?

        无论如何,您可以使用临时表或嵌套查询。

        SELECT
         CASE
          WHEN age_c <18 THEN 'Under 18'
          WHEN age_c BETWEEN 18 AND 24 THEN '18-24'
          WHEN age_c BETWEEN 25 AND 34 THEN '25-34'
        END AS age_range, 
        INTO #TempAges
        FROM contacts
        ORDER BY age_c
        
        SELECT COUNT(*) FROM #TempAges GROUP BY age_range
        

        完成后不要忘记删除临时表

        【讨论】:

        • It doesn't look like it because you're missing a space between 34 and then. That code would error in SQL. 不是真的。 SQL Server 可以毫无问题地解析和执行。
        【解决方案6】:

        age_c 分组——age_range 不是物理列。更具体地说,这样做:

        group by case
           when age_c <18 then 'Under 18'
           when age_c between 18 and 24 then '18-24'
           when age_c between 25 and 34then '25-34'
         END
        

        由于age_range 是一个别名列,group by 根本不知道它。分组发生在计算列集之前。您可以在其中使用别名的唯一子句是order by,因为这是在计算列集之后执行的唯一子句。

        【讨论】:

        • @Sheridanbulger 这正是所要求的并且工作正常。请参阅Grouping By Case Example 的工作示例
        • 哦,对不起。乍一看,我只看到了age_c 分组。你编辑了吗?无论哪种情况,是的,该代码(或任何其他答案)都会很好用。
        • 谢谢。我真的不认为我可以使用 age_range 作为一个列,因为它是一个别名。我正在关注此页面上的示例:[link]stackoverflow.com/questions/3247630/…
        猜你喜欢
        • 2016-11-24
        • 2020-10-27
        • 1970-01-01
        • 2015-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多