我正在尝试构建一个查询,该查询将根据一系列过滤器从数据库中提取事件:baseId,标题,年龄和发生日期。
这是我到目前为止得到的:
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 语句如何)。
如何让查询按每列进行筛选,然后按我想要的每个频率间隔进行筛选?我可能不止 2、4 个...可以有 1、2、4、8、16、32 或 64 的任意组合。
或者,有没有办法使用 FreqInterval 的 SUM 进行AND (FreqType = 8 AND (FreqInterval & 6) = 6)
?我不完全理解按位查询。
添加括号:
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 )
这与按位逻辑无关。 您只需要修复 WHERE
子句,即可使用括号使两个按位比较成为同一计算集的一部分:
...
AND (FreqType = 8 AND (FreqInterval & 2) = 2 OR
FreqInterval & 4) = 4))
你也不需要检查两次FreqType
所以我为你简化了这一点。
OR
意味着可以忽略任何先前的标准。 将其与其他按位检查放在括号中意味着其中一个必须返回 true。
我认为这是一个优先问题。您正在执行的操作:
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))
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))