我正在尝试构建一个查询,该查询将根据一系列过滤器从数据库中提取事件: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的任意组合。
或者,有没有办法使用FreqInterval的SUM进行AND (FreqType = 8 AND (FreqInterval & 6) = 6)
?我不完全理解按位查询。
答案 0 :(得分: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的查询中,为了使它们粘在一起,请在它们周围加上括号。
尽管如此,就像你暗示的那样,我更喜欢这个ツ
(FreqType = 8 AND (FreqInterval & 6) <> 0 )
答案 1 :(得分:2)
这与按位逻辑无关。您只需要修复WHERE
子句,使用括号使两个按位比较成为同一评估集的一部分:
...
AND (FreqType = 8 AND (FreqInterval & 2) = 2 OR
FreqInterval & 4) = 4))
您也不需要检查FreqType
两次,所以我为您简化了这一点。
OR
表示可以忽略任何先前的标准。将其放在括号中并使用其他按位检查意味着其中一个必须返回true。
答案 2 :(得分: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))
答案 3 :(得分:2)
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))