2010-04-26 6 views
2

Existe-t-il un moyen de sélectionner des enregistrements en utilisant une instruction if?PostgreSQL si requête?

Ma table ressemble à ceci:

id | num | dis 
1 | 4 | 0.5234333 
2 | 4 | 8.2234 
3 | 8 | 2.3325 
4 | 8 | 1.4553 
5 | 4 | 3.43324 

Je veux choisir le num et disdis est le chiffre le plus bas ... Donc, une requête qui produira les résultats suivants:

id | num | dis 
1 | 4 | 0.5234333 
4 | 8 | 1.4553 
+0

S'il y a deux lignes avec le même num et dis, mais des identifiants différents, lesquels devraient être retournés? Ou voulez-vous les deux? Ou est-ce impossible? –

+0

Environ combien de lignes y aura-t-il dans votre table? Et combien de groupes? La taille de la table est pertinente pour des raisons de performance. –

Répondre

4

Si vous voulez que toutes les lignes avec la valeur minimale au sein du groupe:

SELECT id, num, dis 
FROM table1 T1 
WHERE dis = (SELECT MIN(dis) FROM table1 T2 WHERE T1.num = T2.num) 

Ou vous pouvez utiliser une jointure pour obtenir le même résultat:

SELECT T1.id, T1.num, T1.dis 
FROM table1 T1 
JOIN (
    SELECT num, MIN(dis) AS dis 
    FROM table1 
    GROUP BY num 
) T2 
ON T1.num = T2.num AND T1.dis = T2.dis 

Si vous voulez seulement une seule rangée de chaque groupe, même s'il y a des liens que vous pouvez utiliser ceci:

SELECT id, dis, num FROM (
    SELECT id, dis, num, ROW_NUMBER() OVER (PARTITION BY num ORDER BY dis) rn 
    FROM table1 
) T1 
WHERE rn = 1 

Malheureusement, cela ne sera pas très efficace. Si vous avez besoin de quelque chose de plus efficace, veuillez consulter la page Quassnoi sur selecting rows with a groupwise maximum for PostgreSQL. Ici, il suggère plusieurs façons d'effectuer cette requête et explique les performances de chacun. Le résumé de l'article est la suivante:

Contrairement à MySQL, PostgreSQL implémente plusieurs façons propres et documentées pour sélectionner les dossiers tenant groupe sages valeurs maximales, y compris les fonctions de fenêtre et DISTINCT ON.

Cependant l'absence de l'indice lâche support d'analyse par l'optimiseur PostgreSQL et de l'utilisation moins efficace des index dans PostgreSQL, les requêtes utilisant ces fonctions prennent trop de temps.

Pour contourner ces problèmes et améliorer les requêtes sur les conditions de regroupement faible de cardinalité, une certaine solution décrite dans l'article doit être utilisé.

Cette solution utilise CTE récursive pour de balayage émuler lâche index et est très efficace si les colonnes de regroupement ont faible cardinalité.

1

Utilisez ceci:

SELECT DISTINCT ON (num) id, num, dis 
FROM tbl 
ORDER BY num, dis 

Ou si vous avez l'intention d'utiliser d'autres SGBDR à l'avenir, utilisez ceci:

select * from tbl a where dis = 
(select min(dis) from tbl b where b.num = a.num) 
Questions connexes