LINUX.ORG.RU

SQL запрос с массивами

 , ,


1

2

Использую СУБД postgresql. Помогите написать запрос. Есть 3 массива со значениями 3 полей таблицы A[a1,a2], B[b1,b2], C[c1,c2] соответственно. Есть запрос:

SELECT *
FROM T
WHERE Field1 = a1 AND Field2 = b1 AND Field3 = c1
UNION
SELECT *
FROM T
WHERE Field1 = a2 AND Field2 = b2 AND Field3 = c2
То есть нужно найти все записи, значения полей которых равны наборам из массивов (a[N],b[N],c[N]). Если массивы большие размером, не хочется лепить запрос через UNION, он выполняется долго и размер этого запроса большой. Может быть можно сократить, что-то типа такого
SELECT *
FROM T
WHERE Field1 = ANY(ARRAY[a1,a2,a3]) AND Field2 = ANY(ARRAY[b1,b2,b3]) AND Field3 = ANY(ARRAY[c1,c2,c3])
Но в таком виде запрос работает неверно, возвращает записи в полях которых входит хотя бы одно значение массива из каждого массива.

Есть 3 массива со значениями 3 полей таблицы A[a1,a2], B[b1,b2], C[c1,c2]

Я ничего не понял. Если ты не можешь даже сформулировать вопрос, то ты должен работать на другой работе. И помощи ты не достоин.

anonymous ()

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

Elyas ★★★★★ ()

Я бы использовал второй вариант запроса, только вместо ANY написать через IN (https://dba.stackexchange.com/questions/125413/index-not-used-with-any-but-us...), есть подозрение, что индекс не используется. Конструирование объекта массива тоже не требуется. Сами индексы тоже надо проверить, да.

После того, как ты таким запросом выберешь все сочетания значений твоих массивов, делаешь первый запрос и выбираешь правильные тройки - должно быть быстро.

Но в любом случае, если оптимизируешь, то нужно смотреть план запроса.

Короче, что-то типа такого:

WITH TT AS (
  SELECT *
  FROM T
  WHERE Field1 IN (a1,a2) AND Field2 IN (b1,b2) AND Field3 IN (c1,c2)
)
SELECT *
FROM TT
WHERE Field1 = a1 AND Field2 = b1 AND Field3 = c1
UNION
SELECT *
FROM TT
WHERE Field1 = a2 AND Field2 = b2 AND Field3 = c2

Лучше всего такой запрос генерировать процедурно - структура у него простая.

Пофиг, что он большой, если ты хочешь оптимизации, то мелкими запросы не будут.

Правильная версия PostgreSQL с возможностью параллелизации запроса тоже может помочь в скорости.

anonymous ()