【发布时间】:2020-09-22 13:08:23
【问题描述】:
这是this question 的后续行动,我从中得到了答案。
如果它们匹配,我仍在尝试将 2 个表中的记录配对。但是我现在需要查看第一个表中的记录,即使第二个记录不存在。
第一个表#T1 包含总是在第二个表#T2 中的事件之前出现的事件。但这一次,#T2 中的匹配事件可能永远不会出现。
第三个表 #E 包含为事件定义分别出现在 #T1 和 #T2 中的值的记录。
套用我上一个问题的答案:
逻辑如下 - 对于 T1 中的每一行 ...
- 在 T2 中查找匹配的行,其中“匹配”表示 a) 相同的 VehicleId,b) 相同的 EventId,c) EventValue 受 #E 中的可能性限制,并且 d) 发生在 T1 中的事件之后
- 从 T2 中为 T1 中的每一行查找第一个(最小)时间戳
- 将 EventDelay 计算为两个时间戳之间的时间
现在最后一个要求是:
- 如果 T2 中没有匹配的行,则只返回关于 T1 的数据。
这看起来就像使用 LEFT JOIN 而不是 INNER JOIN 一样简单,但它不起作用。
下面的新示例数据并尝试新查询仍返回 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 的
where子句引用了left outer join右侧的列,而不允许null。这会将outer join转换为inner join。
标签: sql sql-server tsql subquery left-join