我有一个表,返回一系列布尔值(0/1(和一个运算符(和/或(,如下所示
例如
ID | 运算符 | 值|
---|---|---|
1 | 和 | 0 |
2 | 和 | 0 |
3 | 或 | <1>
通常情况下,人们会使用优先级规则来处理:and
在or
之前,这会使事情变得非常复杂。
但是,如果你想用一种非常简单的堆栈方式来处理它,其中每个项目都是按顺序处理的,你可以用下面的方式重新排列它。
- 由于
(A AND B) OR C
与C OR (A AND B)
相同,我们可以简单地从or
中单独查找所有and
- 我们可以忽略任何为
false
的or
条件,因为任何其他条件都会覆盖它 - 我们需要所有
and
条件为真
SELECT CASE WHEN
(COUNT(CASE WHEN Operator = 'and' AND value = 1 THEN 1 END) > 0
AND COUNT(CASE WHEN Operator = 'and' AND value = 0 THEN 1 END) = 0)
OR COUNT(CASE WHEN Operator = 'or' AND value = 1 THEN 1 END) > 0
THEN 1 ELSE 0 END
FROM YourTable;
你说实际上你确实想要使用优先级规则。你没有括号,所以这会让事情变得更容易。
所以我们可以这样表述:
- 任何为false的
or
都可以忽略 - 任何为true的
or
都会覆盖其他任何内容 - 将所有
and
分组在孤岛中,并分别评估每个孤岛 - 任何一个岛都是真的,其他的都是假的
SELECT CASE WHEN
EXISTS (SELECT 1
FROM YourTable t
WHERE Operator = 'or' AND value = 1)
OR EXISTS (SELECT 1
FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY ID) -
ROW_NUMBER() OVER (PARTITION BY Operator ORDER BY ID) grouping
FROM YourTable t
) t
WHERE Operator = 'and'
GROUP BY grouping
HAVING COUNT(CASE WHEN value = 0 THEN 1 END) = 0
)
THEN 1 ELSE 0 END;