postgresql XOR加入数组值还是null?

时间:2011-11-28 17:52:43

标签: postgresql join

我有两个表,Foo和Bar,我想将它们连接在一起,因此BarID根据数组中的键获取奖励,或者如果没有设置数组,则默认为每个键解锁奖品。

>Table Foo
fooID | someArray    | prize
----------------------------------
 1    | {10,20,30}   | 'Winner'
 2    | {10}         | 'Grand prize'
 3    | null         | 'Participant'

(这不是someArray的字符串,它是有效的postgresql type。)

>Table Bar 
BarID | Key
------------
 1    | 10
 2    | 20
 3    | 30
 4    | 40
 5    | 40
 6    | 40

我在下面尝试了这个:

SELECT
    Foo.fooID,
    Bar.prize
FROM Foo
LEFT JOIN Bar ON Bar.Key = ANY(someArray)

当我输入WHERE子句(例如

)时,我的成功很少
WHERE Bar.BarID = 3

我的结果只是'赢家',但我也希望得到'参与者'。如果我设置我的WHERE以包含空值:

WHERE 
    Bar.BarID = 3
  OR
    Foo.someArray = null

我仍然没有得到我的空值。

否where子句返回值的所有组合,包括空值。

我不确定如何得到我想要的这种行为。我可以得到所有,或者我只能获得一组值,但不能同时获得两者。

举个例子,如果我要为BarID = 1加入,我应该得到“赢家”,“大奖”和“参与者”。如果我选择BarID 5,我只会选择参与者。

2 个答案:

答案 0 :(得分:2)

尝试:

Foo.someArray IS NULL

当应用于NULL值时,等于运算符始终会产生TRUE,而不是NULL。要测试列是否包含NULL值,您需要上面的表达式,而不是 Foo.someArray = NULL

More about that in the manual

您还必须将其置于JOIN条件中,而不是WHERE条款,正如@Michael所评论的那样。像:

LEFT JOIN Bar ON Bar.Key = ANY(Foo.someArray) OR Foo.someArray IS NULL

如果您将其放在WHERE子句中,您可能还会找到Foo.someArray IS NOT NULL的行,但会有不同的奖品。使用LEFT JOINFoo中如果(且仅当)找不到给定Bar的行,则会为NULL的所有列追加Foo个值},包括someArray。这会在NULL条件下检查WHERE

答案 1 :(得分:1)

尝试

ON COALESCE(Bar.Key = ANY(someArray),TRUE)