你是如何在最早的日期加入的?

时间:2017-06-20 20:07:51

标签: sql postgresql

我有两个表,其中包含多个用户日期的操作类型。对于每个用户离开,我想加入最早的后续到达,如果有的话。

表:离开

| user_id_depart | action_type_depart | action_date_depart |
|----------------|--------------------|--------------------|
| 12345          | depart             | 11/10/2016         |
| 12345          | depart             | 6/9/2017           |
| 99887          | depart             | 1/10/2016          |
| 77665          | depart             | 3/10/2016          |
| 77665          | depart             | 6/9/2017           |

表:到达

| user_id_arrive | action_type_arrive | action_date_arrive |
|----------------|--------------------|--------------------|
| 12345          | arrive             | 12/5/2016          |
| 99887          | arrive             | 2/6/2016           |
| 99887          | arrive             | 3/12/2016          |
| 77665          | arrive             | 4/4/2015           |
| 77665          | arrive             | 4/10/2016          |
| 77665          | arrive             | 12/1/2016          |

期望输出:

| user_id | action_depart_date | action_arrive_date | arrived_success |
|---------|--------------------|--------------------|-----------------|
| 12345   | 11/10/2016 0:00    | 12/5/2016 0:00     | 1               |
| 12345   | 6/9/2017 0:00      | NULL               | 0               |
| 99887   | 1/10/2016 0:00     | 2/6/2016 0:00      | 1               |
| 77665   | 3/10/2016 0:00     | 4/10/2016 0:00     | 1               |
| 77665   | 6/9/2017 0:00      | NULL               | 0               |

代码尝试:请参阅http://rextester.com/PAMO75698

SELECT
    *
    ,CASE WHEN t.user_id_arrive IS NULL THEN 0 ELSE 1 END arrived_successfully
FROM    (
        SELECT
            *
        FROM
            depart d
            LEFT JOIN arrive a ON d.user_id_depart = a.user_id_arrive
                                  AND a.action_date_arrive >= d.action_date_depart 
        ) t
ORDER BY user_id_depart, action_date_depart

尝试输出:请参阅'注意事项'误报。

| user_id_d | action_type_d | action_date_d | user_id_a | action_type_a | action_date_a | arrived_success |   | NOTES                                                                   |
|-----------|---------------|---------------|-----------|---------------|---------------|-----------------|---|-------------------------------------------------------------------------|
| 12345     | depart        | 11/10/2016    | 12345     | arrive        | 12/5/2016     | 1               |   | Correct                                                                 |
| 12345     | depart        | 6/9/2017      | NULL      | NULL          | NULL          | 0               |   | Correct                                                                 |
| 77665     | depart        | 3/10/2016     | 77665     | arrive        | 4/4/2015      | 1               |   | INCORRECT-arrive date prior to depart date                              |
| 77665     | depart        | 3/10/2016     | 77665     | arrive        | 4/10/2016     | 1               |   | Correct                                                                 |
| 77665     | depart        | 6/9/2017      | NULL      | NULL          | NULL          | 0               |   | Correct                                                                 |
| 99887     | depart        | 1/10/2016     | 99887     | arrive        | 2/6/2016      | 1               |   | Correct                                                                 |
| 99887     | depart        | 1/10/2016     | 99887     | arrive        | 3/12/2016     | 1               |   | INCORRECT-arrive date is not the earliest date subsequent to the depart |

我的代码尝试中出现误报,因为多行符合条件。如果我可以澄清问题,请发表评论。

1 个答案:

答案 0 :(得分:1)

您可以在left join表格中DEPART获取MIN并使用SELECT D.USER_ID_DEPART AS USER_ID,D.ACTION_DATE_DEPART ,MIN(A.ACTION_DATE_ARRIVE) AS ACTION_DATE_ARRIVE ,(MIN(A.ACTION_DATE_ARRIVE) IS NOT NULL)::INT AS ARRIVED_SUCCESS FROM DEPART D LEFT JOIN ARRIVE A ON A.USER_ID_ARRIVE=D.USER_ID_DEPART AND A.ACTION_DATE_ARRIVE>=D.ACTION_DATE_DEPART GROUP BY D.USER_ID_DEPART,D.ACTION_DATE_DEPART ORDER BY 1,2 获取下一个到达日期(如果有)。

environment