Понимание coalesce в postgres

Точный вопрос.

Table ROW
value1 a
value2 b    
value3 null
value4 d

Параметры функции

CREATE OR REPLACE FUNCTION "GetValues"(
  "@value1"                   VARCHAR(50),
  "@value2"                   VARCHAR(50),
  "@value3"                   VARCHAR(50),
  "@value4"                   VARCHAR(50)
)
BEGIN
  RETURN QUERY SELECT(
      t."value1",
      t."value2",
      t."value3",
      t."value4",
  )
  FROM "table" as t
  WHERE t."value1" = COALESCE("@value1", c."value1")
  AND t."value2" = COALESCE("@value2", c."value2")
  AND t."value3" = COALESCE("@value3", c."value3")
  AND t."value4" = COALESCE("@value4", c."value4");
END;

Если я использую вышеуказанную функцию и предоставляю только следующее:

('a', null, null, 'd')

Он вернет [], даже если найдены 'a' и 'd', и я обнаружил, что это происходит только в том случае, если я предоставлю параметр для поиска чего-то, что является null, и значение строки также будет null.

СТАРОЕ ОПИСАНИЕ НИЖЕ

Я установил получение, которое успешно использует COALESCE для поиска по нескольким или 1 параметрам. Однако, если какой-либо из этих параметров, которые не указаны (по умолчанию NULL), на самом деле имеет значение NULL в базе данных, потому что я не обновлял это поле раньше, тогда он всегда будет возвращать пустой массив, даже если один из предоставленных параметров будет успешным совпадением с строкой в ​​таблице.

Я просто хочу знать, нужна ли мне вся новая система для завершения этого поиска или это просто неудачный эффект COALESCE?

Ниже приведен соответствующий фрагмент.

  FROM "table" as t
  WHERE t."value1" = COALESCE("@value1", c."value1")
  AND t."value2" = COALESCE("@value2", c."value2")
  AND t."value3" = COALESCE("@value3", c."value3")
  AND t."value4" = COALESCE("@value4", c."value4");

В приведенном выше примере, если я предоставлю значение1, и оно совпадает, но значение4 имеет значение NULL в этой строке, то оно вернет [].

Результатом является таблица с каждым из этих 4 значений.

Можете ли вы предоставить схему для соответствующих таблиц / столбцов и указание того, какой результат вы ожидаете?

jmelesky 13.09.2018 20:23
COALESCE(A, B, C, ...) дает первый параметр, который не является NULL. Если все заданные параметры - NULL, тогда функция также возвращает NULL. Так работает COALESCE. Но я действительно не понимаю твоей проблемы. Приведите пример или более точное объяснение.
S-Man 13.09.2018 20:33

Возврат - это таблица RETURN TABLE ("a" VARCHAR (50) ... и т. д.), И COALESCE работает так же. Проблема с запрошенными строками. Если "@ value1" = c. "Value1", а "@ value4" = NULL и c. "Value4" = NULL, потому что эта часть строки пуста, он вернет [], даже если первый запрос вернул совпадение.

Brandon 13.09.2018 21:07

Моя текущая идея, которая у меня есть, что нежелательно, состоит в том, чтобы добавить значение по умолчанию для всех значений (у меня есть другая таблица с 29 строками, поэтому она не идеальна).

Brandon 13.09.2018 21:09

@ S-Man Я задал точный вопрос

Brandon 13.09.2018 22:09

c. была опечатка, поэтому я изменил его на t. Это переменная для ТАБЛИЦЫ. Пример содержимого таблицы находится вверху, где написано Table ROW, per field 1-4 a, null, null, d

Brandon 13.09.2018 22:36

Ваш синтаксис функции, кажется, содержит некоторые ошибки. Таким образом, у него нет типа возврата или фигурных скобок после SELECT, например. Я создал скрипку, как я понял вашу настройку: dbfiddle.uk/… Но мне непонятно, что означает c. Если t опечатка, что это должно быть?

S-Man 13.09.2018 22:45

Мой плохой, c должен был быть b t, t это Таблица from table as t. Частично это был код sudo, потому что фактическое создание очень длинное (29 возвратов, 13 параметров). Если я упросту код, чтобы искать только несколько параметров, я знаю, что он вернет правильную строку (строки). Однако, когда в строках для одного из параметров поиска есть значения null, это не удается. Надеюсь, я адекватно объяснил.

Brandon 13.09.2018 23:30
0
8
743
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Сделать это можно так:

  FROM test as t
  WHERE ("@value1" IS NULL OR t."value1" = "@value1")
  AND ("@value2" IS NULL OR t."value2" = "@value2")
  AND ("@value3" IS NULL OR t."value3" = "@value3")
  AND ("@value4" IS NULL OR t."value4" = "@value4");

db <> рабочий пример

Это потрясающе. Я все еще привыкаю к ​​postgres и вижу такие способы, как проверить, если что-то, не оборачивая его в IF, является большим препятствием для меня.

Brandon 14.09.2018 00:09

Должно ли это быть простое сравнение строк (выдать все строки, которые имеют те же значения, что и входные параметры)?

Этого можно просто добиться с помощью компаратора строк (документация):

WHERE row(t.*) IS NOT DISTINCT FROM row("@value1", "@value2", "@value3", "@value4")

демонстрация: db <> рабочий пример

Если NULL в качестве входного параметра функции должен быть подстановочным знаком, тогда решение @kurkle работает хорошо.

Другие вопросы по теме