【问题标题】:SQL WHERE excluding records using AND and NOTSQL WHERE 使用 AND 和 NOT 排除记录
【发布时间】:2009-06-10 20:49:51
【问题描述】:

这是我正在处理的一个查询:

SELECT  TBL_SUB_KEY AS port
      , poe.[TBL_COMPANY]
      , poe.[TBL_DIVISION_1]
FROM    dbo.TMVKTAB AS poe
WHERE   ( TBL_NUMBER = '8A' )
        AND ( TBL_SUB_KEY <> '' )
        AND ( poe.[TBL_COMPANY] <> '011'
              AND poe.[TBL_DIVISION_1] <> '11'
            )

我要返回的是 Company = '011'/Division_1' = '11' 中的所有记录。

我认为在 () 中合并公司/部门可以实现这一点,但事实并非如此。它消除了所有公司“011”记录,并消除了所有部门“11”记录。

但是,当我这样做时:

SELECT  TBL_SUB_KEY AS port
      , poe.[TBL_COMPANY]
      , poe.[TBL_DIVISION_1]
FROM    dbo.TMVKTAB AS poe
WHERE   ( TBL_NUMBER = '8A' )
        AND ( TBL_SUB_KEY <> '' )
        AND NOT ( poe.[TBL_COMPANY] = '011'
              AND poe.[TBL_DIVISION_1] = '11'
            )

它似乎得到了正确的结果。这是为什么呢?

【问题讨论】:

    标签: sql syntax


    【解决方案1】:

    这是一个布尔逻辑问题:

    NOT (A and B) <=> NOT A  OR NOT B
    

    即:

    NOT ( poe.[TBL_COMPANY] = '011' AND poe.[TBL_DIVISION_1] = '11')
    

    相当于:

    ( poe.[TBL_COMPANY] <> '011' OR poe.[TBL_DIVISION_1] <> '11')
    

    阅读:

    http://en.wikipedia.org/wiki/Boolean_logic

    【讨论】:

    • 噢!我尝试了 OR,但我认为我得到了不正确的结果。再试一次,你是对的。
    • 只要 TBL_COMPANY 和 TBL_DIVISION 都不能为 NULL,就可以了。如果任何一个都可以存储 NULL,那么条件必须要复杂得多: ((poe.TBL_COMPANY '011' OR poe.TBL_COMPANY IS NULL) OR (poe.TBL_DIVISION '11' OR poe.TBL_DIVISION IS NULL) )。 3VL 太有趣了。
    【解决方案2】:

    我认为 NOT 的等价物会使用 OR,如下所示:

    SELECT  TBL_SUB_KEY AS port
          , poe.[TBL_COMPANY]
          , poe.[TBL_DIVISION_1]
    FROM    dbo.TMVKTAB AS poe
    WHERE   ( TBL_NUMBER = '8A' )
            AND ( TBL_SUB_KEY <> '' )
            AND ( poe.[TBL_COMPANY] <> '011'
                  OR poe.[TBL_DIVISION_1] <> '11'
                )
    

    【讨论】:

      【解决方案3】:
      where x and (y and z)
      

      相同
      x and y and z
      

      然而

      where x and not (y and z)
      

      是你想要的,并且有效。

      试试这个:

      SELECT  TBL_SUB_KEY AS port
            , poe.[TBL_COMPANY]
            , poe.[TBL_DIVISION_1]
      FROM    dbo.TMVKTAB AS poe
      WHERE   ( TBL_NUMBER = '8A' )
              AND ( TBL_SUB_KEY <> '' )
              AND NOT ( poe.[TBL_COMPANY] = '011'
                        AND poe.[TBL_DIVISION_1] = '11'
                      )
      

      【讨论】:

        【解决方案4】:

        是时候学习一些布尔代数了。这个:

        not (x and y)
        

        等同于:

        (not x or not y)
        

        所以你的查询应该是:

        SELECT  TBL_SUB_KEY AS port
              , poe.[TBL_COMPANY]
              , poe.[TBL_DIVISION_1]
        FROM    dbo.TMVKTAB AS poe
        WHERE   ( TBL_NUMBER = '8A' )
                AND ( TBL_SUB_KEY <> '' )
                AND ( poe.[TBL_COMPANY] <> '011'
                      OR poe.[TBL_DIVISION_1] <> '11'
                    )
        

        【讨论】:

          【解决方案5】:

          因为不属于公司 011 和部门 11 的记录由

          匹配
                    poe.[TBL_COMPANY] <> '011'
                    OR poe.[TBL_DIVISION_1] <> '11'
          

          如果公司不是 011,部门可以是 11,你仍然会有匹配的组合。

          De Morgan's law 解释了如何以这种方式转换布尔表达式。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多