PostgreSQL unnest avec empty array
j'utilise postgreSQL 9.1. Dans ma base de données il y a une table qui ressemble à
id | ... | values
-----------------------
1 | ... | {1,2,3}
2 | ... | {}
où id est un entier et values est un tableau entier. Les tableaux peuvent être vides.
j'ai besoin de unnest cette liste. Si j'ai une requête
select id, ..., unnest(values)
from table
j'obtiens trois lignes pour id = 1 (comme prévu) et aucune ligne pour id = 2. Est-il possible d'obtenir un résultat semblable à
id | ... | unnest
-------------------
1 | ... | 1
1 | ... | 2
1 | ... | 3
2 | ... | null
c'est à dire une requête qui contient également les lignes qui ont un tableau vide?
5 réponses
select id,
case
when int_values is null or array_length(int_values,1) is null then null
else unnest(int_values)
end as value
from the_table;
(notez que j'ai renommé la colonne values
int_values
values
est un mot réservé et ne doit pas être utilisé comme un nom de colonne).
SQLFiddle: http://sqlfiddle.com/#!1 / a0bb4/1
Postgres 10 ne permet pas d'utiliser unnest()
comme ça, pas plus.
vous devez utiliser une jointure latérale:
select id, t.i
from the_table
cross join lateral unnest(coalesce(nullif(int_values,'{}'),array[null::int])) as t(i);
exemple en ligne: http://rextester.com/ALNX23313
il peut être simplifié encore plus lorsqu'on utilise une jointure à gauche au lieu de la jointure en croix:
select id, t.i
from the_table
left join lateral unnest(int_values) as t(i) on true;
exemple en ligne:http://rextester.com/VBO52351
après avoir réexaminé cette question, je me suis dit que cela pouvait être plus simple et plus rapide.
Inverser la logique de l' solution actuellement acceptée par @a_horse:
SELECT id, CASE WHEN values <> '{}' THEN unnest(values) END AS value
FROM tbl
renvoie une ligne avec
NULL
value
pour un vide ainsi queNULL
array, parce que seul un array avec des éléments produitTRUE
dans le testvalues <> '{}'
.Fonctionne pour les tableaux de tapez, puisque le mot '{}' est automatiquement forcé à un type correspondant.
Sans explicite
ELSE
branche,CASE
retourneNULL
, ce que nous voulons de toute façon.Tableaux
NULL
les éléments retourneront les lignes indépendamment.
cependant. j'y ai trouvé une anomalie et posté une question concernant que:s'est avéré être un bug qui a été corrigé après mon rapport pour pg 9.3+.
select id,
unnest (
"values"
||
(array[null]::integer[])[1:(array_upper("values", 1) is null)::integer]
)
from "table"
Cela fonctionne sur Postgres 10 aussi:
SELECT id, UNNEST(CASE WHEN "values" <> '{}' THEN "values" ELSE '{null}' END)
Vous aurez besoin d'utiliser l'auto LEFT JOIN
, comme ceci (également sur SQL Fiddle):
SELECT t.id, u.u
FROM tab t
LEFT JOIN (SELECT id, unnest(vals) u FROM tab) u
USING (id);
notez que pour les plus grandes tables, la requête va mal fonctionner.