简体   繁体   中英

SQL Query to change group clause

I have a query as follows:

SELECT age_groups.Name as name, avg(scores.score) as avg 
FROM scores 
JOIN users ON scores.id = users.id 
JOIN age_groups on user.age_group = age_groups.id;

There are 5 age groups: 0-10, 11-20, 21-30, 31-40, 41-50.

I'd like to have only three age groups in my results: 0-30, 31-40, and 41-50.

What statements would allow me to group three age groups together?

EDIT:

The age_groups table looks like this:

ID - Name
1 - 0-10
2 - 11-20
3 - 21-30
...etc

You can use case to combine age groups. First, though, your query is missing group by , so it should read more like:

SELECT ag.Name as name, avg(s.score) as avg
FROM scores s JOIN
     users u
     ON s.id = u.id JOIN
     age_groups ag
     on u.age_group = ag.id
GROUP BY ag.Name;

You can then do what you want as:

SELECT (case when ag.Name in ('0-10', '11-20', '21-30') then '0-30'
             else ag.Name
        end) as MyAgeGroup, avg(s.score) as avg
FROM scores s JOIN
     users u
     ON s.id = u.id JOIN
     age_groups ag
     on u.age_group = ag.id
GROUP BY (case when ag.Name in ('0-10', '11-20', '21-30') then '0-30'
               else ag.Name
          end);

One solution is to replace "age_groups.Name" in your select clause with a case statement which remaps each of the contributing ranges to your desired range:

CASE age_groups.Name
  WHEN '0-10'
  THEN '0-30'
  WHEN '10-20'
  THEN '0-30'
  WHEN '20-30'
  THEN '0-30'
  ELSE age_groups.Name
END AS Name

and also add this to the bottom with a GROUP BY clause (eg, GROUP BY CASE WHEN ...)

However, if this type of thing might be done frequently, then I would recommend a longer term solution, which is to add numeric bounds to the age groups in your age group table such as Age_Group_Lower_Bound (integer) and Age_Group_Upper_Bound (integer) (eg, your 0-10 row would then have Age_Group_Lower_Bound=0 and Age_Group_Upper_Bound=10). Once these are in place, your original query could use these, eg,:

CASE
  WHEN age_groups.Age_Group_Upper_Bound <= 30
  THEN '0-30'
  ELSE age_Groups.Name
END

Here's an example of that, taking it further with more ranges getting grouped together, eg:

CASE
  WHEN age_groups.Age_Group_Upper_Bound <= 20
  THEN '0-20'
  WHEN age_groups.Age_Group_Upper_Bound <= 40
  THEN '20-40'
  WHEN age_groups.Age_Group_Upper_Bound <= 60
  THEN '40-60'
  ELSE '60+'
END

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM