Mysql SQL如何对给定范围内的列进行分组,并连接到其他表以计算第一列的相关行

Mysql SQL如何对给定范围内的列进行分组,并连接到其他表以计算第一列的相关行,mysql,sql,postgresql,table-relationships,Mysql,Sql,Postgresql,Table Relationships,我需要根据给定的年份范围对用户列进行分组。这是1980-19891990-19992000-2009年的示例年份范围 然后,我需要加入计算另一个表的结果。我创建了一个数据库用户关系,并创建了两个表来显示我的问题 +--------------------------+ | Tables_in_user_relations | +--------------------------+ | user_answers | | users |

我需要根据给定的年份范围对用户列进行分组。这是1980-19891990-19992000-2009年的示例年份范围 然后,我需要加入计算另一个表的结果。我创建了一个数据库用户关系,并创建了两个表来显示我的问题

+--------------------------+
| Tables_in_user_relations |
+--------------------------+
| user_answers             |
| users                    |
+--------------------------+
2 rows in set (0.00 sec)
这是用户表

+----+----------+-----------+
| id | username | birthyear |
+----+----------+-----------+
|  1 | user1    |      1980 |
|  2 | user2    |      1990 |
|  3 | user3    |      2000 |
|  4 | user4    |      1983 |
+----+----------+-----------+
4 rows in set (0.00 sec)
这是用户回答表。我只需要根据按日期范围分组的用户数来计算用户的答案

+----+---------+-----------+
| id | user_id | option_id |
+----+---------+-----------+
|  1 |       1 |         1 |
|  2 |       2 |         1 |
|  3 |       3 |         2 |
|  4 |       4 |         1 |
+----+---------+-----------+
4 rows in set (0.00 sec)
根据这些表格,我需要得到这样的结果

+------------------------------------------------
| option_id | 1980-1989 | 1990-1999 | 2000-2009 |
+------------------------------------------------
|  1        |         2 |         1 |         0 |
|  2        |         0 |         0 |         1 |
|  3        |         0 |         0 |         0 |
+------------------------------------------------
注意:我需要先使用用户表。我知道可能会有很多变化来得到这个结果。但我必须以这种方式得到结果。这只是一个例子


我希望那边有人能帮助我。谢谢。

您可以在sum中使用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

您可以在sum中使用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

您可以使用枢轴来完成此操作,大致如下所示:

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

您可以使用枢轴来完成此操作,大致如下所示:

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

是mysql还是postgresql?是mysql还是postgresql?顺便说一句,squire括号是MS SQL Server特有的语法。SQL标准和大多数数据库管理系统(包括PostgreSQL)都使用双引号。非常感谢您给出的答案非常好的答案。我想再问一个简单的问题。fauxmosapien提出了支点。哪种解决方案对于较大的数据库具有更好的性能?我不确定,为什么不尝试两种方法并告诉我们呢=我同意你的回答。再次感谢。顺便说一句,squire方括号是MS SQL Server特有的语法。SQL标准和大多数数据库管理系统(包括PostgreSQL)都使用双引号。非常感谢您给出的答案非常好的答案。我想再问一个简单的问题。fauxmosapien提出了支点。哪种解决方案对于较大的数据库具有更好的性能?我不确定,为什么不尝试两种方法并告诉我们呢=我同意你的回答。再次非常感谢,非常感谢你的回答。我现在就去看看。非常感谢你的回答。我现在就去看看。