首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >执行自连接时查询挂起

执行自连接时查询挂起
EN

Stack Overflow用户
提问于 2020-05-11 22:13:19
回答 1查看 22关注 0票数 0

我在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列上执行内部连接,如下所示:

代码语言:javascript
复制
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
EN

Stack Overflow用户

回答已采纳

发布于 2020-05-11 22:23:21

您可以将其简化为以下内容:

代码语言:javascript
复制
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的问题:

代码语言:javascript
复制
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'

这是更多的文本,但对查询的作用要清楚得多。此外,此查询可以更好地使用索引(如果有索引,则创建索引)。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61731795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档