按多个 datediff 分组

Group by multiple datediff

我有这个 table 存储用户最后一次连接到服务器的时间:

+----+----------------------------+-----------+
| id |         last_connection    | something |
+----+----------------------------+-----------+
|  1 | 2017-03-23 10:39:14.000000 | bleh      |
|  2 | 2014-03-20 07:05:51.000000 | blah      |
|  3 | ...                        | ...       |
+----+----------------------------+-----------+

我可以 select 并计算过去 2 个月内活跃的 ID,例如:SELECT count(*) as '2months' FROMstatsWHERE TIMESTAMPDIFF(DAY, SUBSTRING_INDEX(last_connection, ' ', 1), CURDATE()) < 60,或者在过去的 3 个月里 SELECT count(*) as '3months' ... < 90 等等,这让我得到这样的结果:

+---------+
| 2months |
+---------+
|    1337 |
+---------+

我的问题是:有没有一种方法可以在一个唯一的查询中对多个 TIMESTAMPDIFF 进行分组,并得到如下所示的结果?

+-----------+-------+
| last conn | count |
+-----------+-------+
| 1month    |  1337 |
| 2month    | 31337 |
| 3month    |   ... |
| ...       |   ... |
+-----------+-------+
SELECT sum(TIMESTAMPDIFF(DAY, SUBSTRING_INDEX(last_connection, ' ', 1), CURDATE()) < 30) as '1months',
       sum(TIMESTAMPDIFF(DAY, SUBSTRING_INDEX(last_connection, ' ', 1), CURDATE()) < 60) as '2months',
       sum(TIMESTAMPDIFF(DAY, SUBSTRING_INDEX(last_connection, ' ', 1), CURDATE()) < 90) as '3months' 
FROM stats

或更短

SELECT sum(last_connection > current_timestamp - interval 30 day) as '1months',
       sum(last_connection > current_timestamp - interval 60 day) as '2months',
       sum(last_connection > current_timestamp - interval 90 day) as '3months' 
FROM stats

一种方法是使用 UNION 运算符,例如:

SELECT '1month', count(*)  
FROM stats
WHERE  TIMESTAMPDIFF(DAY, SUBSTRING_INDEX(last_connection, ' ', 1), CURDATE()) BETWEEN 0 AND 30

UNION

SELECT '2months', count(*)  
FROM stats
WHERE  TIMESTAMPDIFF(DAY, SUBSTRING_INDEX(last_connection, ' ', 1), CURDATE()) BETWEEN 31 AND 60

UNION

SELECT '3months', count(*)  
FROM stats
WHERE  TIMESTAMPDIFF(DAY, SUBSTRING_INDEX(last_connection, ' ', 1), CURDATE()) BETWEEN 61 AND 90

此外,您需要使用范围而不是 < 运算符来防止重复。