Si j'utilise array_agg
pour collecter des noms, j'obtiens mes noms séparés par des virgules, mais au cas où il y aurait une null
valeur, cette valeur nulle est également considérée comme un nom dans l'agrégat. Par exemple :
SELECT g.id,
array_agg(CASE WHEN g.canonical = 'Y' THEN g.users ELSE NULL END) canonical_users,
array_agg(CASE WHEN g.canonical = 'N' THEN g.users ELSE NULL END) non_canonical_users
FROM groups g
GROUP BY g.id;
il retourne ,Larry,Phil
au lieu de juste Larry,Phil
(dans mon 9.1.2, cela montre NULL,Larry,Phil
). comme dans ce violon
Au lieu de cela, si j'utilise string_agg()
, il ne me montre que les noms (sans virgules vides ni nulles) comme ici
Le problème est que je l' ai Postgres 8.4
installé sur le serveur, et string_agg()
ne fonctionne pas là. Existe-t-il un moyen de faire fonctionner array_agg de la même manière que string_agg ()?
Réponses:
Violon SQL
Ou, plus simple et peut être moins cher, en utilisant
array_to_string
ce qui élimine les valeurs nulles:Violon SQL
la source
array_to_string(array_agg(...))
vous pouvez aussi bien utiliserstring_agg
.Avec postgresql-9.3, on peut faire cela;
Mise à jour : avec postgresql-9.4;
la source
Pour résoudre la question générale de la suppression des valeurs nulles des agrégats de tableaux, il existe deux façons principales d'attaquer le problème: soit en faisant array_agg (unnest (array_agg (x)) soit en créant un agrégat personnalisé.
Le premier est de la forme ci - dessus :
La deuxième:
Appeler le second est (naturellement) un peu plus joli que le premier:
la source
J'ajoute cela même si ce fil est assez ancien, mais je suis tombé sur cette astuce qui fonctionne assez bien sur de petits tableaux. Il fonctionne sur Postgres 8.4+ sans bibliothèques ou fonctions supplémentaires.
La
array_to_string()
méthode supprime en fait les valeurs nulles.la source
Si vous recherchez une réponse moderne à la question générale de savoir comment supprimer un NULL d'un tableau , c'est:
J'étais particulièrement curieux de connaître les performances et je voulais comparer cela à la meilleure alternative possible:
Faire un test pgbench a prouvé (avec une grande confiance) que array_remove () est un peu plus de deux fois plus rapide . J'ai fait mon test sur des nombres à double précision avec une variété de tailles de tableaux (10, 100 et 1000 éléments) et des NULL aléatoires entre les deux.
la source
Comme cela a été suggéré dans les commentaires, vous pouvez écrire une fonction pour remplacer les valeurs nulles dans un tableau, mais comme également souligné dans le fil lié à dans les commentaires, ce type de fonction va à l'encontre de l'efficacité de la fonction d'agrégation si vous devez créer un agrégat , divisez-le puis agrégez-le à nouveau.
Je pense que garder les valeurs nulles dans le tableau n'est qu'une fonctionnalité (peut-être indésirable) de Array_Agg. Vous pouvez utiliser des sous-requêtes pour éviter cela:
SQL FIDDLE
la source
C'est très simple, tout d'abord créez un nouvel opérateur - (moins) pour le texte [] :
Et soustrayez simplement le tableau [null]:
C'est tout:
{O, N}
la source
array_agg(x) FILTER (WHERE x is not null)
semble beaucoup plus facile: dbfiddle.uk/ ... et vous n'avez pas vraiment besoin de votre propre fonction, vous pouvez simplement utiliserarray_remove()
dbfiddle.ukUne question plus importante est de savoir pourquoi tirer tous les combos utilisateur / groupe à la fois. Garanti que votre interface utilisateur ne peut pas gérer toutes ces données. L'ajout de pagination à des données surdimensionnées est également une mauvaise idée. Demandez à vos utilisateurs de filtrer l'ensemble avant de voir les données. Assurez-vous que votre jeu d'options JOIN est dans la liste afin qu'ils puissent filtrer les performances s'ils le souhaitent. Parfois, 2 requêtes rendent les utilisateurs plus heureux s'ils sont tous les deux rapides.
la source