postgresql XOR Присоединиться к значению массива или null? - PullRequest
3 голосов
/ 28 ноября 2011

У меня есть две таблицы, Foo и Bar, я хотел бы объединить их, чтобы BarID получал выигрыш, основываясь на ключе, который находится в массиве, или, если массив не настроен, по умолчанию, как если бы каждый ключ разблокирует приз.

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

(Это не строка для someArray, это действительный тип postgresql .)

>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

Я все еще не получаю свои нулевые значения.

Оператор No where возвращает все комбинации значений, включая нули.

Я не совсем уверен, как получить такое поведение, которое я хочу. Я могу получить все, или я могу получить только один набор значений, но не оба.

Чтобы привести примеры, если я должен выполнить объединение для BarID = 1, я должен получить «Победитель», «Главный приз» и «Участник». Если бы я выбрал BarID 5, я бы получил только Участника.

Ответы [ 2 ]

2 голосов
/ 28 ноября 2011

Попробуйте:

Foo.someArray IS NULL

Оператор равенства всегда выдает NULL, а не TRUE при применении к значению NULL. Чтобы проверить столбец, содержит ли он значение NULL, вам нужно выражение выше, а не Foo.someArray = NULL.

Подробнее об этом в руководстве .

Вы также должны поместить его в ваше JOIN условие, а не в предложение WHERE, как прокомментировал @Michael. Как:

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

Если вы поместите его в предложение WHERE, вы также можете найти строки, где Foo.someArray IS NOT NULL, но имеют разные призы. С LEFT JOIN, если (и только если) не найдена строка в Foo для данного Bar, NULL будут добавлены для всех столбцов Foo, включая someArray. Это обманет проверку для NULL в WHERE условии.

1 голос
/ 28 ноября 2011

Попробуйте

ON COALESCE(Bar.Key = ANY(someArray),TRUE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...