web-dev-qa-db-fra.com

PostgreSQL JOIN avec un type de tableau avec ordre des éléments de tableau, comment mettre en œuvre?

J'ai deux tables dans la base de données:

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

Cette table contient une ligne de données avec un identifiant unique.

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

)

Cette table contient un champ de type tableau. Chaque ligne contient les valeurs des ID de la table items dans un ordre spécifique. Par exemple: {2,4,233,5}.

Maintenant, je veux obtenir des données de la table items pour la ligne choisie de la table some_chosen_data_in_order avec un ordre pour les éléments du type tableau.

Ma tentative était JOIN:

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

La deuxième tentative était une sous-requête comme:

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

Mais aucun d'entre eux ne conserve les identifiants dans le même ordre que dans le champ tableau. Pourriez-vous m'aider, comment obtenir des données de la table items avec une correspondance avec les ID de tableau, dans la table some_chosen_data_in_order pour une ligne spécifique?

30
Adiasz
SELECT t.*
FROM unnest(ARRAY[1,2,3,2,3,5]) item_id
LEFT JOIN items t on t.id=item_id

La requête ci-dessus sélectionne les éléments de la table items avec les identifiants: 1,2,3,2,3,5 dans cet ordre.

56
Marcin Kapusta

Probablement normaliser votre table serait le meilleur conseil que je puisse vous donner.

Le module contrib int_array a une fonction idx qui vous donnera la position d'index de l'int dans le tableau. De plus, il existe une fonction idx sur le wiki snippets qui fonctionne pour les tableaux de tous les types de données.

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)
23
Scott Bailey
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

2
aruis
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 = ?])
0
Roy Merrill