【问题标题】:SQL: No Sub-Query but only JoinsSQL:没有子查询,只有联接
【发布时间】:2017-12-09 05:10:13
【问题描述】:

我正在尝试找到此查询的替代方法,其中不存在子选择但仅连接(左、右、内等)。

select count(SC.NUMBER_C) 
from FNQP2PORTAL.SA.SEC_CAS SC
where SC.NUMBER_C not in (
select E.Reference from 
FNQP2HQ.dbo.Entities E
join FNQP2HQ.dbo.Classes C on C.ID = E.ClassID 
where C.Reference =  'Assembly case')

所以,应该是……

select count(SC.NUMBER_C)
from FNQP2PORTAL.SA.SEC_CAS SC
left join  FNQP2HQ.dbo.Entities E on E.Reference = SC.NUMBER_C and E.Reference IS NULL
inner join FNQP2HQ.dbo.Classes C on C.ID = E.ClassID and C.Reference =  'Assembly case'

有人可以帮我吗?

【问题讨论】:

  • 为什么将 E.Reference IS NULL 作为左连接的一部分?
  • 我想要 SC 中 E 中不存在的所有内容。

标签: sql-server left-join inner-join


【解决方案1】:

试试下面的代码,它可能会抛出错误,因为您没有与我们分享示例数据。但是你应该使用exists子句。

SELECT COUNT(SC.NUMBER_C)     
    FROM FNQP2PORTAL.SA.SEC_CAS SC,
    FNQP2HQ.dbo.Classes C,
    FNQP2HQ.dbo.Entities E
     WHERE C.ID = E.ClassID  
     AND C.Reference = 'Assembly Case'
    and not exists(  
    select 1 from  FNQP2HQ.dbo.Entities E1  
        ON SC.NUMBER_C = E1.Reference)

【讨论】:

  • 此查询无效。当 E 未定义时,您将加入 C.ID = E.ClassID 上的类。
【解决方案2】:

人们使用 WHERE IN 逻辑的一个原因是因为通过连接返回了重复项。所以在这种情况下,将逻辑移动到内部连接可能会导致计数膨胀。以下是您将如何解决该问题的方法:

select count(SC.NUMBER_C) 
from FNQP2PORTAL.SA.SEC_CAS SC
inner join 
    (
        select distinct E.Reference 
        from FNQP2HQ.dbo.Entities E
        join FNQP2HQ.dbo.Classes C on C.ID = E.ClassID 
        where C.Reference =  'Assembly case'
        ) as b
    on b.reference = sc.NUMBER_C 

【讨论】:

    【解决方案3】:

    您发布的查询非常不同。一个是包容性的(其中 SC.NUMBER_C IN.... - 另一个是排他性的(左外连接,其中 E.Reference 为 NULL)。由于这些完全不同的查询,不清楚您要做什么。

    这就是您将如何使用连接而不是子查询来完成您的第一个查询。

    SELECT COUNT(SC.NUMBER_C) 
    FROM FNQP2PORTAL.SA.SEC_CAS SC
    JOIN FNQP2HQ.dbo.Entities E
        ON SC.NUMBER_C = E.Reference
    JOIN FNQP2HQ.dbo.Classes C 
        ON C.ID = E.ClassID 
    WHERE C.Reference = 'Assembly Case'
    

    编辑:

    您需要使用子查询和NOT IN 来获得您在评论中要求的内容。你不能只使用连接。

    SELECT COUNT(SC.NUMBER_C) 
    FROM FNQP2PORTAL.SA.SEC_CAS SC
    WHERE SC.NUMBER_C NOT IN 
        (
            SELECT E.Reference 
            FROM FNQP2HQ.dbo.Entities E
            JOIN FNQP2HQ.dbo.Classes C 
                ON C.ID = E.ClassID 
            WHERE C.Reference = 'Assembly Case'
        )
    

    【讨论】:

    • 这将为我提供 SC 中也在 E 中的所有内容。我想要 SC 中 E 中不存在的所有内容
    • 您的回答与我原来的查询完全一样。感谢您的反馈。
    • @RicoStrydom 不,不是——你使用的是IN,而我使用的是NOT IN。你运行查询了吗?它是不同的,应该是你需要的。如果需要修改,请告诉我,我会尽力提供帮助。
    • 我刚才注意到我粘贴了错误的查询。我应该过去的查询中有“NOT”。我更新了原帖。如果造成混乱,我深表歉意。
    • @RicoSrydom 完全没问题 - 感谢您的澄清。您不能只使用联接的原因是因为您试图将外部联接留在表中,只需要 NULL 值 - 然后从该表中您需要进行内部联接。这不能纯粹通过连接来实现,因此需要子查询。不过,我希望有一些 SQL 专家出现并展示一种更巧妙的方法,所以我会回来查看这篇文章。
    【解决方案4】:
    select count(SC.NUMBER_C) 
    from FNQP2PORTAL.SA.SEC_CAS SC
    INNER JOIN FNQP2HQ.dbo.Entities E on SC.NUMBER_C = E.Reference
    INNER JOIN FNQP2HQ.dbo.Classes C on C.ID = E.ClassID 
    where C.Reference =  'Assembly case'
    

    【讨论】:

    • 你为什么要发布与我已经提供的完全相同的答案?
    • 我们同时发帖。
    猜你喜欢
    • 1970-01-01
    • 2016-03-20
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2021-07-25
    • 1970-01-01
    • 2013-07-29
    相关资源
    最近更新 更多