从数据库表中计算多个值/运算符的布尔结果

Compute a boolean result of multiple value/operator from a database table

提问人:jfrobishow 提问时间:7/14/2021 最后编辑:jfrobishow 更新时间:7/14/2021 访问量:90

问:

我有一个表返回给我一系列布尔值(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。

sql 服务器 t-sql 布尔逻辑

评论

0赞 Tim Schmelter 7/14/2021
您按 ID 订购?
3赞 astentx 7/14/2021
应该在 s 之前应用所有 s,还是应该以堆栈方式处理它们?ANDOR
0赞 Dale K 7/14/2021
可以是任意数量的行?而且你从来没有括号?因为不带括号,您的 OR 将始终覆盖其他所有内容。
1赞 Charlieface 7/14/2021
@DaleK 假设我们采用标准的“前面”,我看不出没有递归的方法,而且我认为这永远不会像简单的循环那样好。简直不敢相信我刚才这么说。andorwhile
1赞 Dale K 7/14/2021
当我说“OR”快捷方式时,我不太正确,实际的规则是“当一个语句中使用多个逻辑运算符时,首先计算 AND 运算符”,这意味着顺序很重要。

答:

2赞 Charlieface 7/14/2021 #1

通常,人们会使用优先级规则来处理它:在 之前,这将使事情变得非常复杂。andor

但是,如果您想以非常简单的堆栈方式处理它,其中每个项目都按顺序处理,则可以按以下方式重新排列它。

  • 由于与 相同,我们可以简单地分别从(A AND B) OR CC OR (A AND B)andor
  • 我们可以忽略任何条件,因为任何其他条件都会覆盖它orfalse
  • 我们需要所有条件都是真实的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
是的,这是一种被称为“间隙和孤岛”的技术