Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 多对多左连接,其中根据最小日期差连接行_Mysql_Sql - Fatal编程技术网

Mysql 多对多左连接,其中根据最小日期差连接行

Mysql 多对多左连接,其中根据最小日期差连接行,mysql,sql,Mysql,Sql,我试图将两个表连接在一起,一个包含事务数据,另一个包含旅行订单数据。我的目标是将transactions表中的每个记录与travel orders表中的单个记录相链接,其中transactions purchase date和travel orders start date之间的差异最小。这些表由SSN连接,我希望使用左连接,因为我希望保留事务数据中的所有记录,即使SSN不存在差旅订单 以下是一些虚构的样本数据: /* Create and populate transactions */

我试图将两个表连接在一起,一个包含事务数据,另一个包含旅行订单数据。我的目标是将transactions表中的每个记录与travel orders表中的单个记录相链接,其中transactions purchase date和travel orders start date之间的差异最小。这些表由SSN连接,我希望使用左连接,因为我希望保留事务数据中的所有记录,即使SSN不存在差旅订单

以下是一些虚构的样本数据:

 /* 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