SQL 如何针对给定范围对列进行分组并加入其他 table 以计算与第一列相关的行
SQL How to group a column for a given range and join to other table for counting related rows with the first column
我需要根据给定的年份范围对用户列进行分组。这是示例年份范围 (1980-1989,1990-1999,2000-2009)
然后,我需要加入计算另一个 table 的结果。我创建了一个数据库 "user_relations" 并创建了两个 table 来显示我的问题。
+--------------------------+
| Tables_in_user_relations |
+--------------------------+
| user_answers |
| users |
+--------------------------+
2 rows in set (0.00 sec)
这是用户 table
+----+----------+-----------+
| id | username | birthyear |
+----+----------+-----------+
| 1 | user1 | 1980 |
| 2 | user2 | 1990 |
| 3 | user3 | 2000 |
| 4 | user4 | 1983 |
+----+----------+-----------+
4 rows in set (0.00 sec)
这是 user_answers table。我只需要根据按日期范围分组的用户数 user_answers。
+----+---------+-----------+
| id | user_id | option_id |
+----+---------+-----------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 2 |
| 4 | 4 | 1 |
+----+---------+-----------+
4 rows in set (0.00 sec)
根据这些 tables,我需要得到这样的结果。
+------------------------------------------------
| option_id | 1980-1989 | 1990-1999 | 2000-2009 |
+------------------------------------------------
| 1 | 2 | 1 | 0 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 0 | 0 |
+------------------------------------------------
注意:我需要先使用用户table。我知道可能会有很多变化来获得这个结果。但是我必须以这种方式得到结果。这只是一个例子。
我希望那边有人能帮助我。谢谢。
为此,您可以在求和中使用 case 语句,相当简单:
select ua.option_id,
sum(case when u.birthyear between 1980 and 1989 then 1 else 0 end) as "1980-1989",
sum(case when u.birthyear between 1990 and 1999 then 1 else 0 end) as "1990-1999",
sum(case when u.birthyear between 2000 and 2009 then 1 else 0 end) as "2000-2009"
from users as u
inner join user_answers as ua
on ua.user_id = u.id
group by ua.option_id
您可以使用 PIVOT 来执行此操作,大致如下:
SELECT * from
(SELECT option_id,
CASE
WHEN birthyear <= 2009 and birthyear >= 2000 THEN '2000-2009'
WHEN birthyear <= 1999 and birthyear >= 1990 THEN '1990-1999'
WHEN birthyear <= 1989 and birthyear >= 1980 THEN '1980-1989'
-- [.... etc etc]
END as ranges,
1 as Responses
FROM users u
INNER JOIN user_answers ua on u.id = ua.userid) source
PIVOT (sum(responses) for ranges in ([2000-2009], [1990-1999],[1980-1989])) as Pivot
我需要根据给定的年份范围对用户列进行分组。这是示例年份范围 (1980-1989,1990-1999,2000-2009) 然后,我需要加入计算另一个 table 的结果。我创建了一个数据库 "user_relations" 并创建了两个 table 来显示我的问题。
+--------------------------+
| Tables_in_user_relations |
+--------------------------+
| user_answers |
| users |
+--------------------------+
2 rows in set (0.00 sec)
这是用户 table
+----+----------+-----------+
| id | username | birthyear |
+----+----------+-----------+
| 1 | user1 | 1980 |
| 2 | user2 | 1990 |
| 3 | user3 | 2000 |
| 4 | user4 | 1983 |
+----+----------+-----------+
4 rows in set (0.00 sec)
这是 user_answers table。我只需要根据按日期范围分组的用户数 user_answers。
+----+---------+-----------+
| id | user_id | option_id |
+----+---------+-----------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 2 |
| 4 | 4 | 1 |
+----+---------+-----------+
4 rows in set (0.00 sec)
根据这些 tables,我需要得到这样的结果。
+------------------------------------------------
| option_id | 1980-1989 | 1990-1999 | 2000-2009 |
+------------------------------------------------
| 1 | 2 | 1 | 0 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 0 | 0 |
+------------------------------------------------
注意:我需要先使用用户table。我知道可能会有很多变化来获得这个结果。但是我必须以这种方式得到结果。这只是一个例子。
我希望那边有人能帮助我。谢谢。
为此,您可以在求和中使用 case 语句,相当简单:
select ua.option_id,
sum(case when u.birthyear between 1980 and 1989 then 1 else 0 end) as "1980-1989",
sum(case when u.birthyear between 1990 and 1999 then 1 else 0 end) as "1990-1999",
sum(case when u.birthyear between 2000 and 2009 then 1 else 0 end) as "2000-2009"
from users as u
inner join user_answers as ua
on ua.user_id = u.id
group by ua.option_id
您可以使用 PIVOT 来执行此操作,大致如下:
SELECT * from
(SELECT option_id,
CASE
WHEN birthyear <= 2009 and birthyear >= 2000 THEN '2000-2009'
WHEN birthyear <= 1999 and birthyear >= 1990 THEN '1990-1999'
WHEN birthyear <= 1989 and birthyear >= 1980 THEN '1980-1989'
-- [.... etc etc]
END as ranges,
1 as Responses
FROM users u
INNER JOIN user_answers ua on u.id = ua.userid) source
PIVOT (sum(responses) for ranges in ([2000-2009], [1990-1999],[1980-1989])) as Pivot