我正在尝试使用HAVING子句过滤GROUP BY CUBE的结果。但是,我需要保留不满足条件组合的行。
我凭直觉尝试:
SELECT [...]
FROM [...]
NOT HAVING (flag_1 = 1 AND flag_2 = 1 AND flag_3 = 1)
GROUP BY CUBE [...]遗憾的是,甲骨文没有将NOT HAVING识别为有效语法。
从数学的角度来看,反转每个单独的条件并不会产生相同的结果:
HAVING (flag_1 != 1 AND flag_2 != 1 AND flag_3 != 1)
如何实现NOT HAVING的逻辑等价物?
注意:我发现了一个与之相关的现有问题,但它特定于Microsoft Access,并且目标不同,因此出现了这个新问题。
发布于 2020-02-20 03:44:59
HAVING子句的数学逆要求您将and更改为OR and,如果列可以为空,也需要null-check。
例如(如果可能为空):
HAVING (nvl(flag_1,1) != 1 OR NVL(flag_2,1) != 1 OR NVL(flag_3,1) != 1) 发布于 2020-02-20 04:05:38
我认为最简单的解决方案就是将其更改为HAVING NOT ...
SELECT [...]
FROM [...]
HAVING NOT (flag_1 = 1 AND flag_2 = 1 AND flag_3 = 1)
GROUP BY CUBE [...]但我经常发现NOT (...)不直观;作为替代方案,@MichaelBroughton的答案解释了如何将逻辑从NOT (x AND y)反转到NOT x OR NOT y
发布于 2020-02-20 04:07:34
这与Michael Broughton的答案相同,我不想重复,但我认为它可以更清楚。如果他想在他的回答中加入任何这一点,我很乐意删除这一条。
要确定NOT (boolean_expression)的逻辑等价物,可以应用德摩根定律。请参阅:https://en.wikipedia.org/wiki/De
基本上,您颠倒了每个术语的逻辑,并将所有and更改为OR,将所有OR更改为and。所以,
NOT (A AND B AND C) ==> (NOT A OR NOT B OR NOT C)但您也需要跟踪空值。下面是这个过程:
从..开始。
HAVING NOT (flag_1 = 1 AND flag_2 = 1 AND flag_3 = 1)首先,添加关于起始表达式中存在的NULL的隐式假设。例如,如果是flag_1=1,那么它当然不是NULL。
HAVING NOT (flag_1 = 1 AND flag_1 IS NOT NULL
AND flag_2 = 1 AND flag_2 IS NOT NULL
AND flag_3 = 1 AND flag_3 IS NOT NULL)现在,应用德摩根定律的第一部分,并颠倒每一项的逻辑。所以,e,g.,flag_1 = 1变成了flag_1 != 1..。
HAVING (flag_1 != 1 AND flag_1 IS NULL
AND flag_2 != 1 AND flag_2 IS NULL
AND flag_3 != 1 AND flag_3 IS NULL)最后,应用德摩根定律的第二部分,切换所有and ->OR,反之亦然。
HAVING (flag_1 != 1 OR flag_1 IS NULL
OR flag_2 != 1 OR flag_2 IS NULL
OR flag_3 != 1 OR flag_3 IS NULL)这就是你的答案。
只使用NOT (flag_1 = 1 AND flag_2 = 1 AND flag_3 = 1)如何?
这不起作用,因为它不能像预期的那样处理空值。在Oracle中,任何与null的比较都是false。所以,
(1 = NULL) ... false
NOT (1 = NULL) ... also false因此,flag_1和flag_2都等于1但flag_3为null的行将不会显示在结果中。
https://stackoverflow.com/questions/60307728
复制相似问题