从数据库 table 计算多个 value/operator 的布尔结果
Compute a boolean result of multiple value/operator from a database table
我有一个 table 返回一系列布尔值 (0/1) 与运算符 (and/or) 配对,如下所示
例如
ID
运算符
价值
1
和
0
2
和
0
3
或
1
我正在尝试找到一种有效的方法来将这些行解析为一个结果,该结果等同于
(false and false or true) //returning true
我认为这在 CLR 中是可能的,但它似乎是我在常规 T-SQL 中可以做的事情。我考虑过接收 table 变量的标量函数。这是我现阶段最好的行动方案吗?
table永远不会很复杂,总是以一个可以忽略的 AND 运算符开始。
正如评论中指出的那样,我打算用一个简单的 AND 来做这件事,如果我有任何 OR 它会简化整个事情,但我怀疑我自己,因为当我在 JS 中尝试这个时它没有似乎不是这样:https://jsfiddle.net/3ctshxae/
编辑:我错误地声明我会将它们作为堆栈处理,因为这最初对我来说是有意义的。我从来没有想过没有括号的运算符命令,因为在编程时根本不会那样写它们。我确实想尊重 AND 的布尔逻辑优先规则。
我知道我可以在 CLR 中执行此操作,只需将逻辑放入其中并获取返回值,但我希望避免超出 T-SQL.
通常人们会使用优先规则来处理这个问题: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;
你说实际上你确实想要使用优先规则。你没有括号,所以这让事情变得更容易。
所以我们可以这样表述:
- 任何
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;
我有一个 table 返回一系列布尔值 (0/1) 与运算符 (and/or) 配对,如下所示
例如
ID | 运算符 | 价值 |
---|---|---|
1 | 和 | 0 |
2 | 和 | 0 |
3 | 或 | 1 |
我正在尝试找到一种有效的方法来将这些行解析为一个结果,该结果等同于
(false and false or true) //returning true
我认为这在 CLR 中是可能的,但它似乎是我在常规 T-SQL 中可以做的事情。我考虑过接收 table 变量的标量函数。这是我现阶段最好的行动方案吗?
table永远不会很复杂,总是以一个可以忽略的 AND 运算符开始。
正如评论中指出的那样,我打算用一个简单的 AND 来做这件事,如果我有任何 OR 它会简化整个事情,但我怀疑我自己,因为当我在 JS 中尝试这个时它没有似乎不是这样:https://jsfiddle.net/3ctshxae/
编辑:我错误地声明我会将它们作为堆栈处理,因为这最初对我来说是有意义的。我从来没有想过没有括号的运算符命令,因为在编程时根本不会那样写它们。我确实想尊重 AND 的布尔逻辑优先规则。
我知道我可以在 CLR 中执行此操作,只需将逻辑放入其中并获取返回值,但我希望避免超出 T-SQL.
通常人们会使用优先规则来处理这个问题:and
在 or
之前,这会使事情变得非常复杂。
但是如果你想以一种非常简单的堆栈方式处理它,其中每个项目都按顺序处理,你可以按以下方式重新排列。
- 由于
(A AND B) OR C
与C OR (A AND B)
相同,我们可以简单地从or
中单独查找所有 - 我们可以忽略
false
的任何or
条件,因为任何其他条件都会覆盖它 - 我们需要所有
and
个条件为真
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;
你说实际上你确实想要使用优先规则。你没有括号,所以这让事情变得更容易。
所以我们可以这样表述:
- 任何
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;