Проверьте, существует ли значение в массиве Postgres
мне нужен способ проверить, существует ли значение в данном массиве. До сих пор я придумал что-то вроде этого
select '{1,2,3}'::int[] @> (ARRAY[]::int[] || value_variable::int)
но я продолжаю думать, что должен быть более простой способ, я просто не вижу его.
Edit: просто понял, что я могу это сделать
select '{1,2,3}'::int[] @> ARRAY[value_variable::int]
это гораздо лучше, и я думаю, будет достаточно, но если у вас есть другие способы сделать это, пожалуйста, поделитесь.
5 ответов
проще с ANY
построить:
SELECT value_variable = ANY ('{1,2,3}'::int[])
правый операнд ANY
(между скобками) может быть либо set (результат подзапроса, например) или an массив. Есть несколько способов его использования:
важно отличия: массив операторы (<@
, @>
et al.) ожидал массив типы операндов и поддержка индексов GIN или GiST в стандартном дистрибутиве PostgreSQL, в то время как ANY
строительство ожидает элемент введите как левый операнд и не поддерживает эти индексы. Пример:
ничего из этого не работает для NULL
элементы. Для проверки NULL
:
следите за эту ловушку я попал, при проверке, если определенное значение отсутствует в массиве, вы не должны делать:
SELECT value_variable != ANY('{1,2,3}'::int[])
но использовать
SELECT value_variable != ALL('{1,2,3}'::int[])
вместо.
но если у вас есть другие способы сделать это, пожалуйста, поделитесь.
вы можете сравнить два массива. Если какое-либо из значений в левом массиве перекрывает значения в правом массиве, то оно возвращает true. Это немного банально, но работает.
SELECT '{1}' && '{1,2,3}'::int[]; -- true
SELECT '{1,4}' && '{1,2,3}'::int[]; -- true
SELECT '{4}' && '{1,2,3}'::int[]; -- false
- в первом и втором запросах value
1
находится в правом массиве - обратите внимание, что второй запрос
true
, хотя значение4
не содержится в нужном массив - для третьего запроса нет значений в левом массиве (т. е.
4
) находятся в правом массиве, поэтому он возвращаетfalse
unnest
можно использовать также.
Он расширяет массив до набора строк, а затем просто проверяет, существует ли значение или нет, так же просто, как использовать IN
или NOT IN
.
например
id => uuid
exception_list_ids => uuid[]
select * from table where id NOT IN (select unnest(exception_list_ids) from table2)
при поиске существования элемента в массиве требуется правильное литье для передачи синтаксического анализатора SQL postgres. Вот один пример запроса с использованием оператора array contains в предложении join:
для простоты я перечисляю только главное:
table1 other_name text[]; -- is an array of text
показанная часть соединения SQL
from table1 t1 join table2 t2 on t1.other_name::text[] @> ARRAY[t2.panel::text]
и работает
on t2.panel = ANY(t1.other_name)
Я просто предполагаю, что дополнительное литье требуется, потому что синтаксический анализ не должен приносить определение таблицы для определения точного типа столбца. Другие, пожалуйста, прокомментируйте это.