SQL仅在最早的日期连接两个表

时间:2017-01-18 11:49:48

标签: sql date join

我不擅长SQL并且无法理解其他答案。

我的请求与这两个类似:Join on earliest dateselect earliest date

我有以下两个表:

T1

user   |  lock_time   
----------------------
a | 2016-11-03 04:53:57
b | 2016-11-14 00:50:38
b | 2016-12-04 20:52:18
c | 2016-11-14 16:36:29
d | 2016-11-14 16:41:01
d | 2016-11-15 11:22:29

T2

user   |  unlock_time   
----------------------
a | 2016-11-04 05:47:51
b | 2016-11-15 13:56:28
b | 2016-12-05 23:10:51
d | 2016-11-15 13:36:29

我希望以这样一种方式加入这些表,即每个lock_time与第一个unlock_time配对,这大于加入的lock_time。因此得到的示例表将是:

user   |  lock_time   | unlock_time
-------------------------------------
a | 2016-11-03 04:53:57 | 2016-11-04 05:47:51
b | 2016-11-14 00:50:38 | 2016-11-15 13:56:28
b | 2016-12-04 20:52:18 | 2016-12-05 23:10:51
d | 2016-11-14 16:41:01 | 2016-11-15 13:36:29

我现在对 lock_time和unlock_time之间的时间感兴趣,所以对于锁定/解锁之间没有可能匹配的情况,应删除该行。

保证在上不会有多个lock_time或unlock_time,但可能存在两个具有不同日期的lock_time,只与一个unlock_time匹配。在这种情况下,我想要第一个 lock_time。

示例:用户A已于2016-11-03和2016-11-04锁定,但仅在2016-11-04解锁。

3 个答案:

答案 0 :(得分:3)

您可以按条件l.user = u.user and l.lock_time < u.unlock_time加入表格,并获得最小unlock_time

select l.user, l.lock_time, min(u.unlock_time) as unlock_time
from
   T1 l
   JOIN T2 u on l.user = u.user and l.lock_time < u.unlock_time
group by l.user, l.lock_time;

<强>更新: 适用于d

的情况

T1

user   |  lock_time   
----------------------
d      | 2016-11-14 16:41:01
d      | 2016-11-15 11:22:29 

T2

user   |  unlock_time   
----------------------
d      | 2016-11-15 13:36:29

和结果:

user   |  lock_time          | unlock_time
-------------------------------------
d      | 2016-11-14 16:41:01 | 2016-11-15 13:36:29

在您获得最小lock_time

之后,您可以获得最小的unlock_time
select l1.user, min(l1.lock_time) lock_time, l1.unlock_time
from (
     SELECT
        l.user,
        l.lock_time,
        min(u.unlock_time) AS unlock_time
     FROM
         T1 l
         JOIN T2 u ON l.user = u.user AND l.lock_time < u.unlock_time
     GROUP BY l.user, l.lock_time
) as l1
group by l1.user, l1.unlock_time

答案 1 :(得分:2)

简单方法 - 使用相关子查询在lock_time之后找到用户的第一个unlock_time:

select t1.user, t1.lock_time,
      (select min(t2.unlock_time) from t2
       where t2.unlock_time > t1.lock_time
         and t1.user = t2.user)
from t1

答案 2 :(得分:-1)

您还没有发布完整的表列详细信息,我根据您的示例编写了查询。它可能会起作用。

select t1.user,t1.lock_time, t2.unlock_time  from T1 t1, T2 t2 where t1.user=t2.user and t2.unlock_time >= t1.lock_time;