2017-08-28 3 views
1

J'ai deux tables dans Postgres. Je veux obtenir les dernières données 3records de la table.impossible d'utiliser LIMIT lors de l'utilisation de la requête corrélée

est inférieure à la requête:

select two.sid as sid, 
     two.sidname as sidname, 
     two.myPercent as mypercent, 
     two.saccur as saccur, 
     one.totalSid as totalSid 
from table1 one,table2 two 
where one.sid = two.sid; 

La requête ci-dessus affiche tous les enregistrements vérification de l'état one.sid = two.sid, je veux que les données récentes 3 fiches (4,5,6) de Tableau 2.

Je sais dans Postgres que nous pouvons utiliser limit pour limiter les lignes à récupérer, mais ici dans la table 2 pour chaque ID j'ai plusieurs lignes. Donc je suppose que je ne peux pas utiliser la limite sur table2 mais que je devrais utiliser sur table1. Aucune suggestion?

table1:

sid totalSid 
1 10 
2 20 
3 30 
4 40 
5 50 
6 60 

table2:

sid sidname myPercent saccur 
1 aaaa  11 11t 
1 bbb   13 13g 
1 ccc   11 11g 
1 qw   88 88k 
//more data for 2,3,4,5.... 
6 xyz 89 895W  
6 xyz1  90 90k 
6 xyz2  91 91p 
6 xyz3  92 92q 
+0

Rechercher l'utilisation de 'cross apply' avec votre limite au lieu d'une 'cross join' ou d'un', 'joindre je pense que posgresql appelle cela une jointure latérale. https://stackoverflow.com/questions/11472790/postgres-analogue-to-cross-apply-in-sql-server Comment identifiez-vous "Recent?" – xQbert

+0

Ou utilisez une fonction de fenêtre, telle que row_number(). – wildplasser

+0

Donc, je ne peux pas utiliser LIMIT pour le scénario mentionné ci-dessus? – user7833845

Répondre

1

Compte tenu de la compréhension de la question a changé une sous-requête simple et rejoindre devrait suffire.

Nous sélectionnons tout de table1 limite à 3 enregistrements dans l'ordre sid desc. Cela nous donne les 3 Sid les plus récents et ensuite joindre à table2 pour obtenir les autres données pertinentes SID. L'hypothèse ici est que SID est unique dans le tableau un et "le plus récent" serait ces enregistrements ayant le SID le plus élevé.

SELECT two.sid as sid 
    , two.sidname as sidname 
    , two.myPercent as mypercent 
    , two.saccur as saccur 
    , one.totalSid as totalSid 
FROM (SELECT * FROM table1 ORDER BY SID DESC LIMIT 3) one 
INNER JOIN table2 two 
    ON one.sid = two.sid; 

* Remarque J'ai supprimé une virgule après un alias ci-dessus.

et ci-dessous nous avons rétabli la syntaxe de jointure ANSI 88 en utilisant la notation.

SELECT two.sid as sid 
    , two.sidname as sidname 
    , two.myPercent as mypercent 
    , two.saccur as saccur 
    , one.totalSid as totalSid 
FROM (SELECT * FROM table1 ORDER BY SID DESC LIMIT 3) one 
    , table2 two 
WHERE one.sid = two.sid; 

Cette syntaxe indique fondamentalement obtenir les 3 derniers SIDs de la table une et jointure croisée (pour chaque enregistrement dans un match à tous les enregistrements de deux) que pour tous les enregistrements dans le tableau deux mais retourner uniquement les enregistrements avoir le même SID des deux côtés. Les compilateurs modernes peuvent être en mesure d'utiliser l'optimisation basée sur les coûts pour améliorer les performances, ce qui annule la nécessité de faire toute la jointure croisée; cependant, l'ordre d'opération indique que c'est ce que la base de données devrait normalement faire. si un et deux sont deux tables de taille substantielle, vous pouvez voir que la jointure croisée peut aboutir à un ensemble de données temporaires très important

+1

Oui, nous pouvons.J'ai revisité la norme ansi 89 dans ma deuxième instruction SQL ci-dessus. – xQbert

+0

Traiter/penser à des données en termes de "SETS" vous aviez besoin d'un ensemble de données qui étaient les 3 SID les plus récents et ensuite vous deviez améliorer cet ensemble pour inclure les informations connexes du tableau 2. Donc nous obtenons un ensemble avec 3 dossiers les plus récents, puis nous avons joint à la table deux pour obtenir les informations connexes. en utilisant une sous-requête nous avons forcé le moteur à "générer" cet ensemble puis nous avons pu l'utiliser pour limiter les données de la table 2! ce simple – xQbert

+0

LOL @ 'J'ai revisité la norme ansi 89'. La prochaine étape serait si le moteur n'implémente pas LIMIT (dans les sous-requêtes ...) – wildplasser