Запросы по столбцу массива из CTE - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть CTE со столбцом массива, и я хочу отфильтровать другой столбец по этому массиву идентификаторов.

with vars as (
  select
    (1, 7, 10000) bubble_ids,
    'Frank' name
)

select * from walruses
inner join tusks on walruses.id = tusks.walrus_id
where (
  name = (select name from vars)
  and tusks.bubble_id IN (select bubble_ids from vars)
);

Это приводит к следующему: ERROR: operator does not exist: integer = record

Я пыталсяunnesting - unnest(bubble_ids) - и это приводит к ERROR: record type has not been registered

Какой правильный способ сделать это?

1 Ответ

0 голосов
/ 14 декабря 2018

(1, 7, 10000) не определяет массив.Это конструктор строки , который создает анонимную запись (с тремя полями).

Литерал массива пишется в квадратных скобках и должен начинаться с ключевого слова array, например array[1, 7, 10000].В качестве альтернативы вы можете записать его в виде строкового значения: '{1,7,1000}'

При использовании CTE в качестве «контейнера» для переменных / параметров я обычно использую перекрестное соединение, чтобы сделать его доступным для запроса.Это меньше, набрав

with vars as (
  select
    array[1, 7, 10000] bubble_ids,
    'Frank' as name --<< you need the AS, because name is a keywod
)
select * 
from walruses
  inner join tusks on walruses.id = tusks.walrus_id
  cross join vars v
where name = v.vars
  and tusks.bubble_id = any(v.bubble_ids);

Я предпочитаю выражение values вместо select для определения постоянных значений.

with vars(bubble_ids, name) as (
  values (array[1, 7, 10000], 'Frank')
)
select * 
from walruses
  inner join tusks on walruses.id = tusks.walrus_id
  cross join vars v
where name = v.vars
  and tusks.bubble_id = any(v.bubble_ids);
...