In SQL, how can you “group by” in ranges?

前端 未结 15 2202
粉色の甜心
粉色の甜心 2020-11-22 15:38

Suppose I have a table with a numeric column (lets call it \"score\").

I\'d like to generate a table of counts, that shows how many times scores appeared in each ran

相关标签:
15条回答
  • 2020-11-22 16:22

    Try

    SELECT (str(range) + "-" + str(range + 9) ) AS [Score range], COUNT(score) AS [number of occurances]
    FROM (SELECT  score,  int(score / 10 ) * 10  AS range  FROM scoredata )  
    GROUP BY range;
    
    0 讨论(0)
  • 2020-11-22 16:24

    Because the column being sorted on (Range) is a string, string/word sorting is used instead of numeric sorting.

    As long as the strings have zeros to pad out the number lengths the sorting should still be semantically correct:

    SELECT t.range AS ScoreRange,
           COUNT(*) AS NumberOfOccurrences
      FROM (SELECT CASE
                        WHEN score BETWEEN 0 AND 9 THEN '00-09'
                        WHEN score BETWEEN 10 AND 19 THEN '10-19'
                        ELSE '20-99'
                   END AS Range
              FROM Scores) t
     GROUP BY t.Range
    

    If the range is mixed, simply pad an extra zero:

    SELECT t.range AS ScoreRange,
           COUNT(*) AS NumberOfOccurrences
      FROM (SELECT CASE
                        WHEN score BETWEEN 0 AND 9 THEN '000-009'
                        WHEN score BETWEEN 10 AND 19 THEN '010-019'
                        WHEN score BETWEEN 20 AND 99 THEN '020-099'
                        ELSE '100-999'
                   END AS Range
              FROM Scores) t
     GROUP BY t.Range
    
    0 讨论(0)
  • 2020-11-22 16:25
    select t.range as score, count(*) as Count 
    from (
          select UserId,
             case when isnull(score ,0) >= 0 and isnull(score ,0)< 5 then '0-5'
                    when isnull(score ,0) >= 5 and isnull(score ,0)< 10 then '5-10'
                    when isnull(score ,0) >= 10 and isnull(score ,0)< 15 then '10-15'
                    when isnull(score ,0) >= 15 and isnull(score ,0)< 20 then '15-20'               
             else ' 20+' end as range
             ,case when isnull(score ,0) >= 0 and isnull(score ,0)< 5 then 1
                    when isnull(score ,0) >= 5 and isnull(score ,0)< 10 then 2
                    when isnull(score ,0) >= 10 and isnull(score ,0)< 15 then 3
                    when isnull(score ,0) >= 15 and isnull(score ,0)< 20 then 4             
             else 5  end as pd
         from score table
         ) t
    
    group by t.range,pd order by pd
    
    0 讨论(0)
  • 2020-11-22 16:28

    Neither of the highest voted answers are correct on SQL Server 2000. Perhaps they were using a different version.

    Here are the correct versions of both of them on SQL Server 2000.

    select t.range as [score range], count(*) as [number of occurences]
    from (
      select case  
        when score between 0 and 9 then ' 0- 9'
        when score between 10 and 19 then '10-19'
        else '20-99' end as range
      from scores) t
    group by t.range
    

    or

    select t.range as [score range], count(*) as [number of occurrences]
    from (
          select user_id,
             case when score >= 0 and score< 10 then '0-9'
             when score >= 10 and score< 20 then '10-19'
             else '20-99' end as range
         from scores) t
    group by t.range
    
    0 讨论(0)
  • 2020-11-22 16:29
    select cast(score/10 as varchar) + '-' + cast(score/10+9 as varchar), 
           count(*)
    from scores
    group by score/10
    
    0 讨论(0)
  • 2020-11-22 16:30

    I see answers here that won't work in SQL Server's syntax. I would use:

    select t.range as [score range], count(*) as [number of occurences]
    from (
      select case 
        when score between  0 and  9 then ' 0-9 '
        when score between 10 and 19 then '10-19'
        when score between 20 and 29 then '20-29'
        ...
        else '90-99' end as range
      from scores) t
    group by t.range
    

    EDIT: see comments

    0 讨论(0)
提交回复
热议问题