0

我正在尝试构建一个查询,该查询将基于一系列过滤器从数据库中提取事件:baseId、title、age 和它将发生的天数。

这是我到目前为止所得到的:

SELECT * FROM [Events]
WHERE BaseId = 574 AND Title LIKE '%occurs%' AND MinAge <= 5 AND MaxAge >= 5 
AND (FreqType = 8 AND (FreqInterval & 2) = 2) 
OR (FreqType = 8 AND (FreqInterval & 4) = 4)

没有 OR 线,它拉得很好。使用 OR 行,它不再关心 BaseId、Title、MinAge 和 MaxAge 列。好吧,它确实如此,但只到 OR 所在的位置......然后它会在 OR 之后拉出所有匹配项(无论前面的 AND 语句如何)。

如何让查询按每列过滤,然后按我想要的每个 FreqInterval 过滤?我可能有不止 2、4... 可能有 1、2、4、8、16、32 或 64 的任意组合。

或者,有没有办法AND (FreqType = 8 AND (FreqInterval & 6) = 6)使用 FreqInterval 的 SUM?我不完全理解按位查询。

4

4 回答 4

3

添加括号:

SELECT * FROM [Events]
WHERE BaseId = 574 AND Title LIKE '%occurs%' AND MinAge <= 5 AND MaxAge >= 5 
AND 
(
   (FreqType = 8 AND (FreqInterval & 2) = 2) 
   OR (FreqType = 8 AND (FreqInterval & 4) = 4) 
)

OR 的运算符优先级低于 AND,您应该在它们周围加上括号。您可以进一步简化它:

   (FreqType = 8 
       AND ( (FreqInterval & 2) = 2 OR (FreqInterval & 4) = 4) )
   )

根据您的建议,这几乎是正确的,但这是正确的:

 (FreqType = 8 
       AND (FreqInterval & 6) <> 0 )

顺便说一句,运算符优先级的另一个术语是运算符粘性,如果要显式编写原始查询,它是:

SELECT * FROM [Events]
WHERE 
( 
  BaseId = 574 AND Title LIKE '%occurs%' AND MinAge <= 5 AND MaxAge >= 5 
  AND (FreqType = 8 AND (FreqInterval & 2) = 2) 
)

OR 

(FreqType = 8 AND (FreqInterval & 4) = 4)

这类似于4 * 3 + 5,乘法的优先级高于加法,因此 3 坚持 4 而不是 5,因此输出为17。如果你的目标是输出32,你应该明确坚持 3 到 5,在 3 和 5 周围加上括号,即4 * (3 + 5)

因此,在您使用 OR 的查询中,为了使它们粘在一起,请在它们周围加上括号。

尽管如此,就像你暗示的那样,我更喜欢这个ツ</p>

 (FreqType = 8 AND (FreqInterval & 6) <> 0 )
于 2012-04-19T13:22:50.447 回答
2

这与按位逻辑无关。您只需要修复您的WHERE子句以使用括号使两个按位比较成为同一评估集的一部分:

...
AND (FreqType = 8 AND (FreqInterval & 2) = 2 OR 
                       FreqInterval & 4) = 4))

您也不需要检查FreqType两次,所以我为您简化了这一点。

OR意味着可以忽略任何先前的标准。将其与其他按位检查放在括号中意味着其中一个必须返回 true。

于 2012-04-19T13:14:30.703 回答
2

我认为这是一个优先问题。你正在做的:

BaseId = 574 AND Title LIKE '%occurs%' AND MinAge <= 5 AND MaxAge >= 5 AND (FreqType = 8 AND (FreqInterval & 2) = 2) 
OR
(FreqType = 8 AND (FreqInterval & 4) = 4)

尝试添加额外的 ()

WHERE BaseId = 574 AND Title LIKE '%occurs%' AND MinAge <= 5 AND MaxAge >= 5 
AND ((FreqType = 8 AND (FreqInterval & 2) = 2) OR (FreqType = 8 AND (FreqInterval & 4) = 4))
于 2012-04-19T13:15:02.577 回答
1
SELECT * FROM [Events]
WHERE BaseId = 574 AND Title LIKE '%occurs%' AND MinAge <= 5 AND MaxAge >= 5 
AND ((FreqType = 8 AND (FreqInterval & 2) = 2) 
OR (FreqType = 8 AND (FreqInterval & 4) = 4))
于 2012-04-19T13:16:16.167 回答