一尘不染

有没有一种方法可以将SQL查询中的WHERE和HAVING子句进行OR运算?

sql

假设我有一个SQL查询

SELECT Label1, Label2, SUM(number) as MySum
FROM MyTable
GROUP BY Label1, Label2

它给我一些结果,例如

Label1 | Label2 | MySum 
-------+--------+------
Foo    | Bar    |   100
Foo    | Baz    |  -100
NotFoo | Bar    |   100
NotFoo | Baz    |  -100

我可以放一个WHEREandHAVING子句来过滤结果

SELECT Label1, Label2, SUM(number) as MySum
FROM MyTable
WHERE Label1 = 'Foo'
GROUP BY Label1, Label2
HAVING MySum > 0

这给了我结果

Label1 | Label2 | MySum 
-------+--------+------
Foo    | Bar    |   100

WHEREHAVINGAND隐含一起编。

是否有类似的语法

SELECT Label1, Label2, SUM(number) as MySum
FROM MyTable
WHERE Label1 = 'Foo'
GROUP BY Label1, Label2
OR HAVING MySum > 0

给出结果

Label1 | Label2 | MySum 
-------+--------+------
Foo    | Bar    |   100
Foo    | Baz    |  -100
NotFoo | Bar    |   100

我可以做

SELECT Label1, Label2, SUM(number) as MySum
FROM MyTable
WHERE Label1 = 'Foo'
GROUP BY Label1, Label2

UNION

SELECT Label1, Label2, SUM(number)
FROM MyTable
GROUP BY Label1, Label2
HAVING MySum > 0

劣势: 这可能是低效率的,因为数据库必须计算Foo | Bar | 100两次该行,发现它是重复的,然后将其丢弃。

我也可以写

SELECT Label1, Label2, SUM(number) as MySum
FROM MyTable
WHERE Label1 = 'Foo'
GROUP BY Label1, Label2

UNION ALL

SELECT Label1, Label2, SUM(number)
FROM MyTable
WHERE Label1 <> 'Foo'
GROUP BY Label1, Label2
HAVING MySum > 0

缺点: 乍看之下,它开始变得不那么容易理解了(可能是最坏的缺点)。

或者

SELECT Label1, Label2, SUM(number) as MySum
FROM MyTable
GROUP BY Label1, Label2
HAVING MySum > 0
OR Label1 = 'Foo'

缺点: 这将使数据库可以做很多额外的工作,将大量的非Foo标签聚集在一起。


阅读 153

收藏
2021-05-23

共1个答案

一尘不染

您的最后一个答案很好:

SELECT Label1, Label2, SUM(number) as MySum
FROM MyTable
GROUP BY Label1, Label2
HAVING MySum > 0
OR Label1 = 'Foo'

您已经说过这里还有很多工作要做,但事实并非如此,因为您必须进行汇总以找出是否MySum>0需要对非Label1='Foo'行进行确定。

2021-05-23