Étant donné la chaîne:
«Je pense que PostgreSQL est astucieux»
Je voudrais opérer sur les mots individuels trouvés dans cette chaîne. Essentiellement, j'ai un autre à partir duquel je peux obtenir des détails sur les mots et je voudrais rejoindre un tableau non imbriqué de cette chaîne dans ce dictionnaire.
Jusqu'à présent, j'ai:
select word, meaning, partofspeech
from unnest(string_to_array('I think that PostgreSQL is nifty',' ')) as word
from table t
join dictionary d
on t.word = d.wordname;
Cela accomplit les principes fondamentaux de ce que j'espérais faire, mais cela ne préserve pas l'ordre des mots d'origine.
Question connexe:
PostgreSQL unnest () avec le numéro d'élément
postgresql
sorting
array
parse
swasheck
la source
la source
Réponses:
WITH ORDINALITY
dans Postgres 9.4 ou version ultérieureLa nouvelle fonctionnalité simplifie cette classe de problèmes. La requête ci-dessus peut maintenant simplement être:
Ou, appliqué à une table:
Détails:
À propos de la
LATERAL
jointure implicite :Postgres 9.3 ou plus ancien - et explication plus générale
Pour une seule chaîne
Vous pouvez appliquer la fonction de fenêtre
row_number()
pour mémoriser l'ordre des éléments. Cependant, avec l'habituel,row_number() OVER (ORDER BY col)
vous obtenez des nombres selon l' ordre de tri , pas la position d'origine dans la chaîne.Vous pouvez simplement omettre
ORDER BY
d'obtenir le poste "tel quel":Performance des
regexp_split_to_table()
dégradés avec des cordes longues.unnest(string_to_array(...))
se balance mieux:Cependant, bien que cela fonctionne normalement et que je ne l'ai jamais vu casser dans des requêtes simples, Postgres n'affirme rien quant à l'ordre des lignes sans explicite
ORDER BY
.Pour garantir le nombre ordinal d'éléments dans la chaîne d'origine, utilisez
generate_subscript()
(amélioré avec le commentaire de @deszo):Pour une table de cordes
Ajouter
PARTITION BY id
à laOVER
clause ...Table de démonstration:
J'utilise
ctid
comme substitut ad hoc pour une clé primaire . Si vous en avez une (ou une colonne unique ), utilisez-la à la place.Cela fonctionne sans aucun identifiant distinct:
SQL Fiddle.
Réponse à la question
la source
SELECT generate_series(1,array_length(word_array,1)), unnest(word_array) FROM ....
. Les 9.3LATERAL
pourraient fournir de meilleures solutions à ce problème.generate_subscripts(arr, 1)
fonctionnerait pas à la place degenerate_series(1, array_upper(arr, 1))
? Je préfère le premier pour plus de clarté.