0

如果这是一个 n00b 问题,我对 SQL 有点陌生,所以请多多包涵。所以我的代码运行类似于以下内容:

(select "Balance."CodeValue" AS "CodeValue"
       , "Balance"."OtherValue" AS "OtherValue" 
from "SomeDB"."dbo"."AValue" "Balance"
where ("Balance"."CodeValue" between 'A' and'Z' 
    or "Balance"."CodeValue" in ('ABCDEFG')) 
and "Balance"."CodeValue" NOT in ('XYZ', '1234', 'Etc') 
or "Balance"."CodeValue" between 'A' and 'Z') "Balance" 
on "SomeMatrix"."CodeValue" = "Balance"."CodeValue"

阅读它,它似乎检查“余额”。“代码值”在 A 和 Z 之间或在 'ABCDEFG' 中,而不是在 'XYZ'、'1234'、'Etc' 或 A 和 Z 之间。不是 A 和 Z 的两个检查相互抵消了吗?

提前感谢您的帮助。

4

4 回答 4

1
select Balance.CodeValue AS CodeValue
       ,Balance.OtherValue AS OtherValue 
from SomeDB.dbo.AValue Balance INNER JOIN SomeMatrix
on SomeMatrix.CodeValue = Balance.CodeValue
where 
(
  Balance.CodeValue between 'A' and'Z' ----\
OR                                          -- Either of this is true
  Balance.CodeValue in ('ABCDEFG')     ----/
)     
AND                                    -- AND
(
  Balance.CodeValue 
         NOT IN ('XYZ', '1234', 'Etc')  ----\
OR                                           -- Either of this is true
  Balance.CodeValue between 'A' and 'Z' ----/
) 

运算符的优先级是NOT --> AND --> OR

当您的 WHERE 子句中有一些复杂/棘手的 NOT INs 、 ANDs 和 ORs 时,括号中的相关条件 ()会使您的代码更容易阅读和调试。

于 2014-02-03T23:27:59.567 回答
0

不,他们不会。SQL 适用于“限制”(字面意思)。首次运行查询时

select * from table

它从表中提取所有行然后让我们说这个查询

select * from table where table.column>5

它“隐藏”(再次字面意思)所有小于或等于 5 的行

等等。所以当你输入

select * from table table.column>5 AND table.column>5

它隐藏了相同的值,你会得到正确的结果

编辑: 实际上它适用于添加行。条件 table.column>5 AND tavle.column>5 对于每个特定行将是真或假,并且确定是否在结果中添加行

于 2014-02-03T23:20:11.030 回答
0

我认为您对评估“and”和“or”的顺序感到困惑。将返回满足这三个要求中的任何一个的值:

1) Balance.CodeValue不在('XYZ', '1234', 'Etc'),Balance.CodeValue在'A'和'Z'之间

2) Balance.CodeValue 不在 ('XYZ', '1234', 'Etc') 中,Balance.CodeValue 在 ('ABCDEFG')

3) Balance.CodeValue 在“A”和“Z”之间

最后一个“或”条件(“A”和“Z”之间的Balance.CodeValue)与前面的3个条件是分开的,因为“和”在“或”之前被评估。前三个条件有点粘在一起。

(对不起我草率的术语!我知道逻辑,只是不合适的词来描述它。)

于 2014-02-03T23:23:16.747 回答
0

如上所述,您是正确的,第一位没有做任何事情,因为它被最后一位否定:

;WITH cte AS (SELECT 'XYZ' AS CodeValue
              UNION 
              SELECT 'A')
SELECT *
FROM cte
WHERE (CodeValue between 'A' and'Z'  or CodeValue in ('ABCDEFG')) 
      AND CodeValue NOT in ('XYZ', '1234', 'Etc') 
      OR CodeValue between 'A' and 'Z' 

XYZ即使在该部分XYZ中列出,也会返回。NOT IN

演示:SQL 小提琴

于 2014-02-03T23:23:49.057 回答