我在SQL Server中遇到了一个与比较同一个表中的行是否存在值相关的问题。该表是一个更大的查询的一部分,正在内部联接中使用,以获取匹配的记录。我的问题是,我在inner join中使用的CASE表达式,特别是我使用带有NOT EXISTS子句的自连接的部分,会使整个查询挂起。基本上,它一直在产生一个结果。我认为有些地方是错误的,特别是在这一部分( self join和NOT EXISTS子句的使用)。有人能帮我找出我做错了什么吗?我的主要问题是,如果在Tab2中有一行ServiceType是“电动的”,而DepID是“DISCON”的,它应该总是选择“电动的”。在大多数情况下,“电”和“水”都存在。在LocID 500735中看到的独特情况是,只有“水”存在。我希望它在这里应用“水”ServiceType,但前提是该LocID没有“电动”。我确信我的查询有问题。有没有办法解决这个问题,或者有没有更好的方法来实现我想让查询做的事情?
我的主表Tab1 (T1)包含以下列和示例数据:

我的第二个表Tab2 (T2)包含以下列和示例数据:

我在Tab1和Tab2之间的LocID列上执行内部连接,如下所示:
select T1.LocID, T1.DepID, T2.ServiceType from Tab1 T1
inner join Tab2 T2
ON CASE
WHEN T2.ServiceType='ELECTRIC' AND T1.DepID LIKE '%ELEC%' AND T2.LocID = T1.LocID THEN 1
WHEN T2.ServiceType='ELECTRIC' AND T1.DepID='DISCON DEP' AND T2.LocID = T1.LocID THEN 1
WHEN T2.ServiceType='WATER' AND T1.DepID = 'DISCON DEP' AND T2.LocID = T1.LocID AND NOT EXISTS
(SELECT 1 FROM Tab2 T20
WHERE T2.LocID = T20.LocID
AND T20.ServiceType='ELECTRIC'
AND T20.LocID = T2.LocID) THEN 1
WHEN T2.ServiceType='WATER' AND T1.DepID LIKE '%WATER%' AND T2.LocID = T1.LocID THEN 1
WHEN T2.ServiceType='WATER' AND T1.DepID = 'DISCON DEP WAT' AND T2.LocID = T1.LocID THEN 1
ELSE 0
END = 1发布于 2020-05-11 22:23:21
您可以将其简化为以下内容:
SELECT T1.LocID, T1.DepID, T2.ServiceType
FROM Tab1 T1
INNER JOIN Tab2 T2
ON T2.LocID = T1.LocID
AND (
(T2.ServiceType='ELECTRIC' AND T1.DepID LIKE '%ELEC%')
OR (T2.ServiceType='WATER' AND T1.DepID = 'DISCON DEP' AND NOT EXISTS
(SELECT 1 FROM Tab2 T20
WHERE T2.LocID = T20.LocID
AND T20.ServiceType='ELECTRIC'
AND T20.LocID = T2.LocID))
OR (T2.ServiceType='ELECTRIC' AND T1.DepID='DISCON DEP')
OR (T2.ServiceType='WATER' AND T1.DepID LIKE '%WATER%')
OR (T2.ServiceType='WATER' AND T1.DepID = 'DISCON DEP WAT')
)这可能不会解决您的性能问题,为了解决您可以尝试将查询重写为UNION的问题:
SELECT T1.LocID, T1.DepID, T2.ServiceType
FROM Tab1 T1
INNER JOIN Tab2 T2
ON T2.LocID = T1.LocID
AND T2.ServiceType='ELECTRIC'
AND T1.DepID LIKE '%ELEC%'
UNION ALL
SELECT T1.LocID, T1.DepID, T2.ServiceType
FROM Tab1 T1
INNER JOIN Tab2 T2
ON T2.LocID = T1.LocID
AND T2.ServiceType='WATER'
AND T1.DepID = 'DISCON DEP'
AND NOT EXISTS
(SELECT 1 FROM Tab2 T20
WHERE T2.LocID = T20.LocID
AND T20.ServiceType='ELECTRIC'
AND T20.LocID = T2.LocID))
)
UNION ALL
SELECT T1.LocID, T1.DepID, T2.ServiceType
FROM Tab1 T1
INNER JOIN Tab2 T2
ON T2.LocID = T1.LocID
AND T2.ServiceType='ELECTRIC'
AND T1.DepID='DISCON DEP'
UNION ALL
SELECT T1.LocID, T1.DepID, T2.ServiceType
FROM Tab1 T1
INNER JOIN Tab2 T2
ON T2.LocID = T1.LocID
AND T2.ServiceType='WATER'
AND T1.DepID LIKE '%WATER%'
UNION ALL
SELECT T1.LocID, T1.DepID, T2.ServiceType
FROM Tab1 T1
INNER JOIN Tab2 T2
ON T2.LocID = T1.LocID
AND T2.ServiceType='WATER'
AND T1.DepID = 'DISCON DEP WAT'这是更多的文本,但对查询的作用要清楚得多。此外,此查询可以更好地使用索引(如果有索引,则创建索引)。
https://stackoverflow.com/questions/61731795
复制相似问题