PostgreSQL JOIN с типом массива с порядком элементов массива, как реализовать? - PullRequest
33 голосов
/ 21 марта 2010

У меня есть две таблицы в базе данных:

CREATE TABLE items(
 id SERIAL PRIMARY KEY,
 ... some other fields
);

Эта таблица содержит строку данных с уникальным идентификатором.

CREATE TABLE some_chosen_data_in_order(
 id SERIAL PRIMARY KEY,
 id_items INTEGER[],
);

Эта таблица содержит поле типа массива. Каждая строка содержит значения идентификаторов из таблицы items в определенном порядке. Например: {2,4,233,5}.

Теперь я хочу получить данные из таблицы items для выбранной строки из таблицы some_chosen_data_in_order с порядком элементов в типе массива.

Моя попытка была ПРИСОЕДИНЕНА:

SELECT I.* FROM items AS I 
JOIN some_chosen_data_in_order AS S ON I.id = ANY(S.id_items) WHERE S.id = ?

Вторая попытка была подобна подзапросу:

SELECT I.* FROM items AS I 
WHERE I.id = ANY 
(ARRAY[SELECT S.id_items FROM some_chosen_data_in_order  WHERE id = ?])

Но ни один из них не хранит идентификаторы в том же порядке, что и в поле массива. Не могли бы вы мне помочь, как получить данные из таблицы items, соответствующие порядку идентификаторов массива из таблицы some_chosen_data_in_order для конкретной строки?

Ответы [ 4 ]

62 голосов
/ 04 сентября 2012
SELECT t.*
FROM unnest(ARRAY[1,2,3,2,3,5]) item_id
LEFT JOIN items t on t.id=item_id

Приведенный выше запрос выбирает элементы из таблицы items с идентификаторами: 1,2,3,2,3,5 в указанном порядке.

24 голосов
/ 22 марта 2010

Вероятно, нормализация вашего стола будет лучшим советом, который я могу вам дать.

В модуле contrib int_array есть функция idx, которая выдаст вам позицию индекса int в массиве. Также на вики snippets wiki есть функция idx, которая работает с массивами любых типов данных.

SELECT i.*, idx(id_items, i.id) AS idx
FROM some_chosen_data_in_order s
JOIN items i ON i.id = ANY(s.id_items)
ORDER BY idx(id_items, i.id)
2 голосов
/ 27 апреля 2018
select distinct on (some_chosen_data_in_order.id)
  some_chosen_data_in_order.*,
   array_to_json( array_agg(row_to_json( items))
  over ( partition by some_chosen_data_in_order.id ))
from some_chosen_data_in_order
  left join items on items.id = any (some_chosen_data_in_order.id_items)

enter image description here

0 голосов
/ 28 мая 2015
SELECT I.* FROM items AS I 
WHERE I.id IN (SELECT UNNEST(id_items) FROM some_chosen_data_in_order 
(ARRAY[SELECT S.id_items FROM some_chosen_data_in_order  WHERE id = ?])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...