Mysql 多对多左连接,其中根据最小日期差连接行
我试图将两个表连接在一起,一个包含事务数据,另一个包含旅行订单数据。我的目标是将transactions表中的每个记录与travel orders表中的单个记录相链接,其中transactions purchase date和travel orders start date之间的差异最小。这些表由SSN连接,我希望使用左连接,因为我希望保留事务数据中的所有记录,即使SSN不存在差旅订单 以下是一些虚构的样本数据:Mysql 多对多左连接,其中根据最小日期差连接行,mysql,sql,Mysql,Sql,我试图将两个表连接在一起,一个包含事务数据,另一个包含旅行订单数据。我的目标是将transactions表中的每个记录与travel orders表中的单个记录相链接,其中transactions purchase date和travel orders start date之间的差异最小。这些表由SSN连接,我希望使用左连接,因为我希望保留事务数据中的所有记录,即使SSN不存在差旅订单 以下是一些虚构的样本数据: /* Create and populate transactions */
/* Create and populate transactions */
CREATE TABLE transactions (
ssn INT,
purchase_date DATE,
price FLOAT
);
INSERT INTO transactions VALUES
(1111, "2018-12-31", 12.20),
(1111, "2018-11-01", 22.23),
(2222, "2018-08-17", 99.23),
(4444, "2018-06-07", 13.22),
(5555, "2018-03-05", 22.22),
(6666, "2018-05-29", 11.11),
(7777, "2018-10-10", 23.32),
(8888, "2018-06-21", 44.44),
(8888, "2018-01-19", 55.55),
(8888, "2018-02-25", 66.53);
/* Create and populate travel orders */
CREATE TABLE travel_orders (
ssn_id INT NOT NULL,
start_date DATE
);
INSERT INTO travel_orders VALUES
(1111, "2018-12-28"),
(1111, "2018-12-07"),
(2222, "2018-08-12"),
(7777, "2018-10-10"),
(7777, "2018-10-14"),
(8888, "2018-06-18"),
(8888, "2018-01-19"),
(8888, "2018-02-22");
例如,事务表记录
(8888, "2018-06-21", 44.44)
将加入旅行订单记录
(8888, "2018-06-18")
其余的记录也是如此
编辑:预期的输出类似于:
+------+---------------+-------+--------+------------+
| ssn | purchase_date | price | ssn_id | start_date |
+------+---------------+-------+--------+------------+
| 1111 | 2018-12-31 | 12.2 | 1111 | 2018-12-28 |
| 1111 | 2018-11-01 | 22.23 | 1111 | 2018-12-07 |
| 2222 | 2018-08-17 | 99.23 | 2222 | 2018-08-12 |
| 4444 | 2018-06-07 | 13.22 | 4444 | NULL |
| 5555 | 2018-03-05 | 22.22 | 5555 | NULL |
| 6666 | 2018-05-29 | 11.11 | 6666 | NULL |
| 7777 | 2018-10-10 | 23.32 | 7777 | 2018-10-10 |
| 8888 | 2018-06-21 | 44.44 | 8888 | 2018-06-18 |
| 8888 | 2018-01-19 | 55.55 | 8888 | 2018-01-19 |
| 8888 | 2018-02-25 | 66.53 | 8888 | 2018-02-22 |
+------+---------------+-------+--------+------------+
我的一些基本启动代码是
SELECT t.*,
o.*
FROM transactions AS t
LEFT JOIN travel_orders AS o
ON t.ssn = o.ssn_id;
但是我需要添加过滤器,根据购买日期和开始日期之间的最小日期差匹配记录。此查询将为您提供所需的结果。它为
ssn
和购买日期(子查询)的每个组合查找购买日期和开始日期之间的最短时间,然后将其加入事务
和差旅订单
表,以获得所需的输出:
SELECT t.*,
o.*
FROM transactions t
JOIN (SELECT t.ssn,
t.purchase_date,
MIN(ABS(DATEDIFF(o.start_date, t.purchase_date))) AS dd
FROM transactions t
LEFT JOIN travel_orders o
ON t.ssn = o.ssn_id
GROUP BY t.ssn, t.purchase_date) d
ON d.ssn = t.ssn AND d.purchase_date = t.purchase_date
LEFT JOIN travel_orders o
ON o.ssn_id = t.ssn AND ABS(DATEDIFF(o.start_date, t.purchase_date)) = d.dd
ORDER BY t.ssn, t.price
输出:
ssn purchase_date price ssn_id start_date
1111 2018-12-31 12.2 1111 2018-12-28
1111 2018-11-01 22.23 1111 2018-12-07
2222 2018-08-17 99.23 2222 2018-08-12
4444 2018-06-07 13.22 (null) (null)
5555 2018-03-05 22.22 (null) (null)
6666 2018-05-29 11.11 (null) (null)
7777 2018-10-10 23.32 7777 2018-10-10
8888 2018-06-21 44.44 8888 2018-06-18
8888 2018-01-19 55.55 8888 2018-01-19
8888 2018-02-25 66.53 8888 2018-02-22