将来自两个 table 的行配对,如果第二个 table 中不存在,则仅显示第一个 table 的内容

Pairing rows from two tables and show only content of first table if it does not exist in second table

这是 的跟进,我从中得到了答案。

我仍在尝试配对来自 2 table 的记录(如果它们匹配)。但是我现在需要查看第一个 table 中的记录,即使第二个记录不存在。

第一个 table #T1 包含的事件总是先于第二个 table #T2 中的事件发生。但这次#T2 中的匹配事件可能永远不会出现。

第三个 table #E 包含为事件定义分别来自 #T1 和 #T2 的值的记录。

解释一下我之前问题的答案:

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

现在最后一个要求是:

这看起来就像使用 LEFT JOIN 而不是 INNER JOIN 一样简单,但它不起作用。

下面的新示例数据并尝试一个新查询,该查询仍然 returns 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子句中的条件移动到left joinon子句中。否则,它将成为强制性的,并且在 t2 中没有匹配的行被归档 - 因为它们的 EventTimestampnull,因此不满足不等式条件。

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