将来自两个 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 中的每一行 ...
- 在 T2 中找到匹配的行,其中 'matching' 表示 a) 相同的 VehicleId,b) 相同的 EventId,c) EventValue 受#E 中可能性的限制,d) 在 T1 中的事件之后发生
- 从 T2 中为 T1 中的每一行查找第一个(最小)时间戳
- 将 EventDelay 计算为两个时间戳之间的时间
现在最后一个要求是:
- 如果T2中没有匹配的行,return只有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 join
的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
这是
我仍在尝试配对来自 2 table 的记录(如果它们匹配)。但是我现在需要查看第一个 table 中的记录,即使第二个记录不存在。
第一个 table #T1 包含的事件总是先于第二个 table #T2 中的事件发生。但这次#T2 中的匹配事件可能永远不会出现。
第三个 table #E 包含为事件定义分别来自 #T1 和 #T2 的值的记录。
解释一下我之前问题的答案:
逻辑如下 - 对于 T1 中的每一行 ...
- 在 T2 中找到匹配的行,其中 'matching' 表示 a) 相同的 VehicleId,b) 相同的 EventId,c) EventValue 受#E 中可能性的限制,d) 在 T1 中的事件之后发生
- 从 T2 中为 T1 中的每一行查找第一个(最小)时间戳
- 将 EventDelay 计算为两个时间戳之间的时间
现在最后一个要求是:
- 如果T2中没有匹配的行,return只有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 join
的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