2017-09-08 1 views
2

La description dans tilte peut ne pas être exactement ce que je veux. Voici un exemple. Étant donné une table t1:PostgreSQL: sélectionne les lignes avec la valeur min dans une colonne parmi les lignes avec des colonnes identiques

src dest length path 
a e 5 a b e 
a d 2 a c d 
a g 6 a c g 
a e 3 a c e 
a e 4 a g e 
a d 2 a b d 

Pour chaque paire (src, dest), s'il n'y a qu'une seule entrée, conservez-la; S'il y a plusieurs entrées, sélectionnez celle qui a la longueur minimale, si elles sont identiques, gardez-les toutes. La sortie doit être:

src dest length path 
a d  2 a c d 
a g  6 a c g 
a e  3 a c e 
a d  2 a b d 

Comment puis-je aborder en utilisant PostgreSQL?

+0

qu'avez-vous essayé jusqu'à présent? – mabe02

+0

https://stackoverflow.com/questions/tagged/postgresql+greatest-n-per-group –

Répondre

0

Je ne pense pas que vous pouvez le faire sans table de balayage deux fois:

t=# with g as (select src,dest,min(length) from t1 group by src,dest) 
select t1.* from t1 
join g on t1.src = g.src and t1.dest = g.dest and length = min 
; 
src | dest | length | path 
-----+------+--------+------ 
a | d |  2 | acd 
a | d |  2 | abd 
a | e |  3 | ace 
a | g |  6 | acg 
(4 rows) 
+0

Plus besoin de joindre ou de scanner deux fois si vous utilisez des fonctions de fenêtre. Voir [la réponse de Gordon Linoff] (https://stackoverflow.com/a/46113750/108326). – markusk

+0

oui, un 'dense_rank()' est une bonne idée ici –

2

Je voudrais utiliser les fonctions de la fenêtre:

select t.* 
from (select t.*, 
      dense_rank() over (partition by src, dest order by length) as seqnum 
     from t 
    ) t 
where seqnum = 1; 
+0

Y a-t-il une bonne raison de préférer 'dense_rank' à' rank' ici? Les deux devraient produire le même résultat pour cette requête, puisque vous ne vérifiez que le rang 1. – markusk

+0

@markusk. . . Aucune raison du tout. J'utilise habituellement 'rank()' parce qu'il est plus court (et plus facile à taper). –

+0

Votre requête ne correspond pas exactement à la sortie désirée, elle inclut également le rang en tant que colonne supplémentaire. Facilement corrigé en réécrivant la requête la plus externe sur 'select src, dest, length, path de (...) où seqnum = 1'. – markusk