Sql 将两个表中的行配对,如果第一个表的内容不在第二个表中,则只显示第一个表的内容
这是一个后续的问题,我从中得到了答案 如果两个表中的记录匹配,我仍在尝试将它们配对。但是我现在需要查看第一个表中的记录,即使第二个记录不存在 第一个表#T1包含始终位于第二个表#T2中的事件之前的事件。但这一次#T2中的匹配事件可能永远不会出现 第三个表#E包含为事件定义分别位于#T1和#T2中的值的记录 我对上一个问题的回答是: 逻辑如下-对于T1中的每一行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中的事件之后发生
- 在T2中查找匹配行,其中“匹配”表示a)相同的车辆ID,b)相同的事件ID,c)事件值受#E中的可能性限制,d)在T1中的事件之后发生
- 从T2中为T1中的每一行查找第一个(最小)时间戳
- 将EventDelay计算为两个时间戳之间的时间
- 如果T2中没有匹配行,则只返回关于T1的数据
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
。将外部联接
转换为内部联接
。