如何根据时间限制将表B的记录定位到表A的ID?

时间:2019-01-28 20:23:08

标签: sql sql-server

目标:我想将transaction_id与transcation_id时间戳记的20分钟内在系统中输入的第一条注释匹配。

情况:两个表均通过电子邮件链接。例如,以aa@email.com的电子邮件作为transaction_id,于2019年1月1日凌晨3:59记录。我想看看是否在20个月内插入了便条。因此,应将表2的注释1作为目标。基本上是第一次出现。对于第二笔交易(与电子邮件zz@email.com相关联),由于第一笔便笺插入> 20mns,因此不会附加任何便笺。

表1:

+---------------------+---------------+------------------+
| timestamp           |    email      |   transaction_id |
+---------------------+---------------+---------------- -+
| 2019-01-01 03:59:00 | aa@email.com  |    123           |
| 2018-12-31 09:00:00 | zz@email.com  |    456           |
+---------------------+-------------+--------------------+

表2:

+--------------+--------+---------------------+
|    email     |  note  |      timestamp      |
+--------------+--------+---------------------+
| aa@email.com | note 1 | 2019-01-01 04:00:00 |
| aa@email.com | note 2 | 2019-01-01 04:15:00 |
| aa@email.com | note 3 | 2019-01-01 04:20:00 |
| aa@email.com | note 4 | 2019-01-01 04:25:00 |
| aa@email.com | note 5 | 2019-01-01 06:15:00 |
| zz@email.com | note 1 | 2019-01-01 08:15:00 |
| zz@email.com | note 2 | 2019-01-01 08:16:00 |
|              |        |                     |
+--------------+--------+---------------------+

输出:

+---------------------+--------------+----------------+-------+---------------------+--+
|      timestamp      |    email     | transaction_id | note  |   note_timestamp    |  |
+---------------------+--------------+----------------+-------+---------------------+--+
| 2019-01-01 03:59:00 | aa@email.com |            123 | note1 | 2019-01-01 04:00:00 |  |
+---------------------+--------------+----------------+-------+---------------------+--+

我尝试过的事情:

SELECT t1.timestamp
    ,t1.email
    ,t1.transaction_id
    ,Emails
    ,Dates
FROM t1
    INNER JOIN 
        (
        SELECT t2.email AS Emails
            ,t2.note AS Notes
            ,t2.timestamp AS Dates
            ,ROW_NUMBER()
                OVER(PARTITION BY t2.email ORDER BY t2.timestamp ASC) AS Top1_note
        FROM t2
        ) AS Subquery 
    ON t1.email=Subquery.Emails

我不确定要放置WHEREHAVING作为条件,以将票据的日期限制为交易日期之后的2,000万毫秒

3 个答案:

答案 0 :(得分:2)

您可以使用CROSS APPLY在20分钟内获取所有笔记。使用row_number()仅获取最早的音符(其中之一)。

SELECT *
       FROM table1 t1
            CROSS APPLY (SELECT *,
                                row_number() OVER (ORDER BY timestamp) rn
                                FROM table2 t2
                                     WHERE t2.email = t1.email
                                           AND t2.timestamp >= t1.timestamp
                                           AND t2.timestamp <= dateadd(minute, 20, t1.timestamp)) x
       WHERE x.rn = 1;

db<>fiddle

答案 1 :(得分:1)

这里是使用窗口函数的另一种方法。

查询首先(在接下来的20分钟之内)选择与交易相关的所有票据,然后对相关子查询使用NOT EXISTS条件,以仅保留最新的子查询。

SELECT
    t1.*, t2.note, t2.timestamp note_timestamp
FROM 
    table1 t1
    INNER JOIN table2 t2 
        ON t1.email = t2.email
        AND t2.timestamp >=  t1.timestamp 
        AND t2.timestamp < DATEADD(MINUTE, 20, t1.timestamp)
WHERE 
    NOT EXISTS (
        SELECT 1
        FROM table2
        WHERE 
            email = t2.email
            AND timestamp > t2.timestamp
            AND timestamp < DATEADD(MINUTE, 20, t1.timestamp)
    )

答案 2 :(得分:1)

尝试一下,

 SELECT  TOP 1 t1.[timestamp] ,t1.[Email],t1.transaction_id 
      ,t2.[Note]
      ,t2.[timestamp] as  note_timestamp
       FROM table1 t1 inner Join table2 t2
       on t2.email = t1.email
       And   t2.timestamp >= t1.timestamp
       AND t2.timestamp <= dateadd(minute, 20, t1.timestamp)