提问人:jfrobishow 提问时间:7/14/2021 最后编辑:jfrobishow 更新时间:7/14/2021 访问量:90
从数据库表中计算多个值/运算符的布尔结果
Compute a boolean result of multiple value/operator from a database table
问:
我有一个表返回给我一系列布尔值(0/1)和一个运算符(和/或),如下所示
例如:
编号 | 算子 | 价值 |
---|---|---|
1 | 和 | 0 |
2 | 和 | 0 |
3 | 或 | 1 |
我试图找到一种有效的方法,将这些行解析为相当于
(false and false or true) //returning true
我认为这在 CLR 中是可能的,但它似乎是我可以在常规 T-SQL 中做的事情。我考虑过标量函数接收表变量。这是我现阶段最好的行动方案吗?
该表永远不会非常复杂,并且始终以可以忽略的 AND 运算符开头。
正如评论中指出的那样,我将使用一个简单的 AND 来做到这一点,如果我有任何 OR,它会缩短整个事情的快捷方式,但我怀疑我自己,因为当我在 JS 中尝试时,情况似乎并非如此:https://jsfiddle.net/3ctshxae/
编辑:我错误地表示我会将它们作为堆栈进行处理,因为这最初对我来说是有意义的。我从来没有想过没有括号的运算符的顺序,因为在编程时根本不会这样写它们。我确实想尊重 AND 优先的布尔逻辑的优先规则。
我知道我可以在 CLR 中执行此操作,只需将逻辑放入其中并获取返回值,但我希望避免跳出 T-SQL。
答:
2赞
Charlieface
7/14/2021
#1
通常,人们会使用优先级规则来处理它:在 之前,这将使事情变得非常复杂。and
or
但是,如果您想以非常简单的堆栈方式处理它,其中每个项目都按顺序处理,则可以按以下方式重新排列它。
- 由于与 相同,我们可以简单地分别从
(A AND B) OR C
C OR (A AND B)
and
or
- 我们可以忽略任何条件,因为任何其他条件都会覆盖它
or
false
- 我们需要所有条件都是真实的
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
- 任何真实的东西都会覆盖其他任何东西
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;
评论
0赞
jfrobishow
7/14/2021
我的问题不正确,评论让我意识到我确实打算在优先级规则完好无损的情况下处理它们。编辑了问题。
1赞
Charlieface
7/14/2021
@jfrobishow好的,我也给了你一个解决方案
0赞
jfrobishow
7/15/2021
效果很好,谢谢!我从未见过像您这样通过计算完成的分组。我认为这是配对“岛屿”,是吗?
1赞
Charlieface
7/15/2021
是的,这是一种被称为“间隙和孤岛”的技术
评论
AND
OR
and
or
while