【问题标题】:Why <> operator fails and returns all the records?为什么 <> 运算符失败并返回所有记录?
【发布时间】:2018-12-10 14:42:03
【问题描述】:

在过去的 1 小时里,我一直在为这个查询拔头发,这是结果

select ac.* from [finance].[Accounts] ac
    inner join finance.AccountMapping ap
    on ap.Account_ID <> ac.AccountID

在帐户表中,我们有一个帐户 ID 1,2,3,4,5,6 在 AccountMapping 表中,我们有一个 account_ID 1,2

但上面的查询仍然返回 1,2 的记录。为什么?我已经提到返回不匹配的记录。

【问题讨论】:

  • ac.AcountID = 3 或以上则与 1,2 不同
  • 因为1 &lt;&gt; 3 等等...
  • 您似乎在寻找not in 过滤器。
  • ap.AccountID = 2 不等于ac.AccountID = 1
  • 所以 AC 的每条记录都与 ap 的所有记录匹配?

标签: sql sql-server sql-server-2008 tsql stored-procedures


【解决方案1】:

因为ac 中的每条记录可能在ap 中至少有一条记录,其中值不匹配。您可能打算:

select ac.*
from finance.Accounts ac left join
     finance.AccountMapping ap
      on ap.Account_ID = ac.AccountID
where ap.Account_ID is null;

或者,这可能更直接一点:

select ac.*
from finance.Accounts ac
where not exists (select 1
                  from finance.AccountMapping ap
                  where ap.Account_ID = ac.AccountID
                 );

【讨论】:

  • Gordon,将其切换为 LEFT JOIN。我们知道您想执行 LEFT ANTI JOIN ;p
【解决方案2】:

您正在寻找可以通过 EXCEPT 实现的结果:

Select AccountID from AccountMapping
Except
Select AccountID from Accounts 

【讨论】:

    【解决方案3】:

    您误解了内连接的ON 子句的工作方式:对于第一个表的每条记录,它会在连接表中找到满足条件的所有 条记录。只要你在外键到主键上做一个等值连接,你最多得到一个记录。一旦您切换到&lt;&gt;&gt;&lt; 等,您可能会为第一个表的每条记录获得多个连接记录。

    在您的示例中,您正在查找 ID 不匹配的所有行。这是存在量词的完美案例,即EXISTS 运算符:

    SELECT *
    FROM [finance].[Accounts] ac
    WHERE NOT EXISTS (
        SELECT *
        FROM finance.AccountMapping ap
        WHERE ap.Account_ID = ac.AccountID
    )
    

    【讨论】:

      【解决方案4】:

      尝试左连接,第二个表的 Account_ID 为空条件:

      SELECT ac.* from [finance].[Accounts] ac
      LEFT JOIN finance.AccountMapping ap
      ON ap.Account_ID= ac.AccountID'
      WHERE ap.Account_ID IS NULL
      

      希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 2017-11-03
        • 1970-01-01
        • 2013-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多