MySQL 具有聚合函数的两行之间的日期差异

MySQL Date difference between two rows with aggregate function

我有一个 table 作为

id     client_id          date
1      1001               2008-11-26 00:00:00
2      2001               2008-09-01 00:00:00
3      2001               2008-08-31 00:00:00
4      1001               2007-08-26 00:00:00
5      3001               2003-11-26 00:00:00
6      1001               2003-05-05 00:00:00

我只想计算相同 client_id 和 select 的两个连续行之间的日期差异 client_id,其日期差异 大于或等于 30 天

在 MySQL < 8.0 中,window 功能不可用,请考虑:

SELECT t.*, t1.date next_date, DATEDIFF(t1.date, t.date) date_diff
FROM mytable t
INNER JOIN mytable t1
    ON  t1.client_id = t.client_id
    AND DATEDIFF(t1.date, t.date) >= 30
    AND NOT EXISTS (
        SELECT 1 
        FROM mytable t2
        WHERE 
            t2.client_id = t.client_id 
            AND t2.date > t.date
            AND t2.date < t1.date
    )
ORDER BY t.client_id, t.date

此查询为您提供同一客户的下一条记录超过 30 天的记录。它通过自连接 table 并应用以下条件来工作:

  • 加入的记录应该属于同一个客户
  • 其日期应至少比当前记录的日期晚 30 天
  • 同一个客户不应该存在另一个记录,其日期大于当前记录的日期且小于加入记录的日期(这实现了 next[=32 的概念=]记录)

Demo on DB Fiddle:

您的示例数据(正确排序):

| id  | client_id | date       |
| --- | --------- | ---------- |
| 6   | 1001      | 2003-05-05 |
| 4   | 1001      | 2007-08-26 |
| 1   | 1001      | 2008-11-26 |
| 3   | 2001      | 2008-08-31 |
| 2   | 2001      | 2008-09-01 |
| 5   | 3001      | 2003-11-26 |

查询结果:

| id  | client_id | date       | next_date  | date_diff |
| --- | --------- | ---------- | ---------- | --------- |
| 4   | 1001      | 2007-08-26 | 2008-11-26 | 458       |
| 6   | 1001      | 2003-05-05 | 2007-08-26 | 1574      |

这是我的解决方案。由于 MySQL 版本不允许使用 LEAD() 函数。要搜索下一个日期,我使用查询 SELECT date FROM mytable WHERE client_id = t.client_id AND t.id < id LIMIT 1

SELECT client_id 
FROM (SELECT t.*, (SELECT date FROM mytable WHERE client_id = t.client_id AND t.id < id LIMIT 1) AS lead_date
FROM mytable t) t2 
WHERE ABS(datediff(lead_date, date)) >= 30 GROUP BY client_id

我发现它很有趣,你也一样, 如我所见,数据是虚拟的,并且 id 对于较旧的日期更大,我忽略了 id 字段

select * 来自 ( select client_id,maxs,max(all_dt) as sec,datediff(maxs,max(all_dt)) as diff from ( select * 来自 ( select client_id,max(dt) 作为最大值 来自 table_name t 按 client_id 分组 )mx 左连接 ( select client_id client_id_all,dt as all_dt 来自 table_name t2 )全部_ 在 mx.client_id=all_.client_id_all 按 mx.client_id 排序 )F 其中 all_dt < maxs 和 client_id=client_id_all 按 client_id 分组 )master where diff >=30

单一日期记录且差异小于30的客户id将不会在输出中列出。

希望对您有所帮助。

祝你好运