Sql 将两个表中的行配对,如果第一个表的内容不在第二个表中,则只显示第一个表的内容

Sql 将两个表中的行配对,如果第一个表的内容不在第二个表中,则只显示第一个表的内容,sql,sql-server,tsql,subquery,left-join,Sql,Sql Server,Tsql,Subquery,Left Join,这是一个后续的问题,我从中得到了答案 如果两个表中的记录匹配,我仍在尝试将它们配对。但是我现在需要查看第一个表中的记录,即使第二个记录不存在 第一个表#T1包含始终位于第二个表#T2中的事件之前的事件。但这一次#T2中的匹配事件可能永远不会出现 第三个表#E包含为事件定义分别位于#T1和#T2中的值的记录 我对上一个问题的回答是: 逻辑如下-对于T1中的每一行 在T2中查找匹配行,其中“匹配”表示a)相同的车辆ID,b)相同的事件ID,c)事件值受#E中的可能性限制,d)在T1中的事件之后发生

这是一个后续的问题,我从中得到了答案

如果两个表中的记录匹配,我仍在尝试将它们配对。但是我现在需要查看第一个表中的记录,即使第二个记录不存在

第一个表#T1包含始终位于第二个表#T2中的事件之前的事件。但这一次#T2中的匹配事件可能永远不会出现

第三个表#E包含为事件定义分别位于#T1和#T2中的值的记录

我对上一个问题的回答是:

逻辑如下-对于T1中的每一行

  • 在T2中查找匹配行,其中“匹配”表示a)相同的车辆ID,b)相同的事件ID,c)事件值受#E中的可能性限制,d)在T1中的事件之后发生
  • 从T2中为T1中的每一行查找第一个(最小)时间戳
  • 将EventDelay计算为两个时间戳之间的时间
最后一个要求是:

  • 如果T2中没有匹配行,则只返回关于T1的数据
这似乎和使用左连接而不是内部连接一样简单,但它不起作用

在下面添加新的示例数据,并尝试执行新的查询,该查询仍然返回2条记录,而不是3条记录

CREATE TABLE #T1 
(
    EventTimestamp DateTime, 
    VehicleId int, 
    EventId varchar(50), 
    EventValue varchar(50)
);

CREATE TABLE #T2 
(
    EventTimestamp DateTime, 
    VehicleId int, 
    EventId varchar(50), 
    EventValue varchar(50)
);

CREATE TABLE #E 
(
     EventId varchar(50), 
     FirstValue int, 
     LastValue varchar(50)
);

INSERT INTO #T1(EventTimestamp, VehicleId , EventId, EventValue)
VALUES (GETDATE(), 1, 'TwigStatus', '12'),
       (GETDATE(), 2, 'SafeProtectEvent', '5'),
       (DATEADD(minute, 10, GETDATE()), 1, 'TwigStatus', '12')

INSERT INTO #T2(EventTimestamp, VehicleId , EventId, EventValue)
VALUES (DATEADD(second, 30, GETDATE()), 1, 'TwigStatus', '7'),
       (DATEADD(second, 30, GETDATE()), 2, 'SafeProtectEvent', '6')

INSERT INTO #E(EventId, FirstValue, LastValue)
VALUES ('TwigStatus', '12', '7'),
       ('SafeProtectEvent', '5', '6')

; WITH ord AS
        (SELECT     t1.VehicleId, 
                    t1.EventTimestamp AS first, 
                    t2.EventTimestamp AS last,
                    t1.EventId, 
                    t2.EventValue,
                    ROW_NUMBER() OVER (PARTITION BY t1.VehicleId, t1.EventTimestamp, t1.EventId ORDER BY t1.EventTimestamp) AS rn
            FROM    #T1 AS t1
                    LEFT JOIN #T2 AS t2 ON t1.VehicleID = t2.VehicleID AND t1.EventID = t2.EventID
                    LEFT JOIN #E AS e ON t1.EventId = e.EventId 
                                      AND t1.EventValue = e.FirstValue
                                      AND t2.eventId = e.EventId 
                                      AND t2.EventValue = e.LastValue
            WHERE   t2.EventTimestamp > t1.EventTimestamp
        )

    SELECT      VehicleId, first, last, EventId, EventValue,
                DATEDIFF(second, first, last) AS EventDelay
        FROM    ord
        WHERE   rn = 1

DROP TABLE #E;
DROP TABLE #T1;
DROP TABLE #T2;
您的CTE看起来像:

SELECT ...
FROM #t1 t1
LEFT JOIN #t2 t2 ON ...
LEFT JOIN #E  e  ON ...
WHERE t2.EventTimestamp > t1.EventTimestamp
where
子句中的条件移动到
左连接的
on
子句中。否则,它将成为强制性的,并且在
t2
中不匹配的行将被归档-因为它们的
EventTimestamp
null
,因此不满足不等式条件

WITH ord AS
        (SELECT     t1.VehicleId, 
                    t1.EventTimestamp AS first, 
                    t2.EventTimestamp AS last,
                    t1.EventId, 
                    t2.EventValue,
                    ROW_NUMBER() OVER (PARTITION BY t1.VehicleId, t1.EventTimestamp, t1.EventId ORDER BY t1.EventTimestamp) AS rn
            FROM    #T1 AS t1
                    LEFT JOIN #T2 AS t2 ON t1.VehicleID = t2.VehicleID 
                                        AND t1.EventID = t2.EventID 
                                        AND t2.EventTimestamp > t1.EventTimestamp
                    LEFT JOIN #E AS e ON t1.EventId = e.EventId 
                                      AND t1.EventValue = e.FirstValue
                                      AND t2.eventId = e.EventId 
                                      AND t2.EventValue = e.LastValue
        )

    SELECT      VehicleId, first, last, EventId, EventValue,
                DATEDIFF(second, first, last) AS EventDelay
        FROM    ord
        WHERE   rn = 1
您的CTE看起来像:

SELECT ...
FROM #t1 t1
LEFT JOIN #t2 t2 ON ...
LEFT JOIN #E  e  ON ...
WHERE t2.EventTimestamp > t1.EventTimestamp
where
子句中的条件移动到
左连接的
on
子句中。否则,它将成为强制性的,并且在
t2
中不匹配的行将被归档-因为它们的
EventTimestamp
null
,因此不满足不等式条件

WITH ord AS
        (SELECT     t1.VehicleId, 
                    t1.EventTimestamp AS first, 
                    t2.EventTimestamp AS last,
                    t1.EventId, 
                    t2.EventValue,
                    ROW_NUMBER() OVER (PARTITION BY t1.VehicleId, t1.EventTimestamp, t1.EventId ORDER BY t1.EventTimestamp) AS rn
            FROM    #T1 AS t1
                    LEFT JOIN #T2 AS t2 ON t1.VehicleID = t2.VehicleID 
                                        AND t1.EventID = t2.EventID 
                                        AND t2.EventTimestamp > t1.EventTimestamp
                    LEFT JOIN #E AS e ON t1.EventId = e.EventId 
                                      AND t1.EventValue = e.FirstValue
                                      AND t2.eventId = e.EventId 
                                      AND t2.EventValue = e.LastValue
        )

    SELECT      VehicleId, first, last, EventId, EventValue,
                DATEDIFF(second, first, last) AS EventDelay
        FROM    ord
        WHERE   rn = 1

您的CTE的
where
子句引用
左侧外部联接右侧的一列,不允许
null
。将
外部联接
转换为
内部联接
。您的CTE的
where
子句引用
左侧外部联接
右侧的列,而不允许
null
。将
外部联接
转换为
内部联接