【发布时间】:2022-01-20 09:03:13
【问题描述】:
例如,获取两者:
- table_1 中日期前 5 天与 table_2 中每日值的最大值
- table_1 中的日期后 5 天与 table_2 中的每日值的最大值
table1 (uid = id) - 日期窗口基于此表中的日期
| id | date |
|---|---|
| a | 2021-12-10 |
| b | 2021-12-21 |
表 2 (uid = id + date) - 每日表
| id | date | value |
|---|---|---|
| a | 2021-12-01 | 0 |
| a | 2021-12-02 | 3 |
| a | ... | ... |
| a | 2021-12-31 | 1 |
| b | 2021-12-01 | 4 |
| b | ... | ... |
| b | 2021-12-31 | 0 |
输出表(uid = id)
| id | date | start_dt_before | end_dt_before | max_value_before | start_dt_after | end_dt_after | max_value_after |
|---|---|---|---|---|---|---|---|
| a | 2021-12-10 | 2021-12-05 | 2021-12-09 | 3 | 2021-12-10 | 2021-12-14 | 4 |
| b | 2021-12-21 | 2021-12-16 | 2021-12-20 | 2 | 2021-12-21 | 2021-12-25 | 5 |
在两个单独的连接中两次查询其中一个表似乎非常耗费资源。有没有办法在单个查询中更优化地查询这个?
编辑——为每个请求添加示例代码
-- Create table_1
CREATE TABLE table_1 (id CHAR(1), event_dt DATE);
INSERT INTO table_1 (id,event_dt) VALUES ('a','2021-12-10');
INSERT INTO table_1 (id,event_dt) VALUES ('b','2021-12-21');
-- Create table_2
CREATE TABLE table_2 (id CHAR(1), day_dt DATE, value INT);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-01',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-02',3);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-03',7);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-04',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-05',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-06',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-07',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-08',3);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-09',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-10',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-11',4);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-12',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-13',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-14',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-15',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-16',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-17',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-18',9);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-19',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-20',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-21',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-22',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-23',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-24',9);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-25',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-26',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-27',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-28',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-29',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-30',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('a','2021-12-31',1);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-01',4);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-02',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-03',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-04',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-05',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-06',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-07',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-08',9);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-09',9);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-10',9);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-11',9);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-12',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-13',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-14',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-15',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-16',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-17',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-18',2);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-19',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-20',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-21',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-22',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-23',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-24',5);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-25',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-26',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-27',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-28',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-29',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-30',0);
INSERT INTO table_2 (id,day_dt,value) VALUES ('b','2021-12-31',0);
-- Example queries that creates desired output:
SELECT
x.id
, x.event_dt
, x.before_min_dt
, x.before_max_dt
, x.before_value
, MIN(t2.day_dt) after_min_dt
, MAX(t2.day_dt) after_max_dt
, MAX(t2.value) after_value
FROM(
SELECT
t1.id
, t1.event_dt
, MIN(t2.day_dt) before_min_dt
, MAX(t2.day_dt) before_max_dt
, MAX(t2.value) before_value
FROM table_1 t1
JOIN table_2 t2
ON (t1.id = t2.id
AND t2.day_dt >= DATE_ADD(t1.event_dt, INTERVAL -5 DAY)
AND t2.day_dt < t1.event_dt)
GROUP BY
t1.id
, t1.event_dt
) x
JOIN table_2 t2
ON (x.id = t2.id
AND t2.day_dt >= x.event_dt
AND t2.day_dt < DATE_ADD(x.event_dt, INTERVAL 5 DAY))
GROUP BY
x.id
, x.event_dt
, x.before_min_dt
, x.before_max_dt
, x.before_value;
【问题讨论】:
-
一个连接,然后是 2 个具有单独窗口定义的窗口函数。
-
您使用的是哪个版本的 MySQL?那么确切的日期呢?
2021-12-10...是包含在-5天还是+5天? -
@Akina 听起来很理想,你能举个例子吗?谢谢
-
将样本数据提供为 CREATE TABLE + INSERT INTO 格式化代码,并严格提供此数据所需的表格格式输出。
-
@Akina 谢谢,我已经添加了示例数据的脚本和生成所需输出的示例查询