2010-02-12 8 views
5

Comme, il ya le mot-clé supérieur dans SQL Server 2005, comment sélectionner la première rangée dans mysql si j'ai joint sur plusieurs tables & voulez extraire extrême de chaque ID/colonne. Limite restreint le non. de la ligne retourne donc il ne peut pas résoudre mon problème.MYSQL top N lignes de plusieurs tables rejoindre

+0

Peut-être un exemple? – hsz

+0

Oui, la question n'est pas très claire. J'ai juste deviné –

+0

La question n'est pas très claire, mais je suppose que c'est un autre cas du problème «le plus grand-n-par-groupe» qui revient fréquemment. –

Répondre

3
SELECT v.* 
FROM document d 
OUTER APPLY 
     (
     SELECT TOP 1 * 
     FROM version v 
     WHERE v.document = d.id 
     ORDER BY 
       v.revision DESC 
     ) v 

ou

SELECT v.* 
FROM document d 
LEFT JOIN 
     (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY v.id ORDER BY revision DESC) 
     FROM version 
     ) v 
ON  v.document = d.id 
     AND v.rn = 1 

Ce dernier est plus efficace si vos documents ont généralement quelques révisions et vous devez sélectionner tous ou presque tous les documents; le premier est plus efficace si les documents ont de nombreuses révisions ou si vous devez sélectionner un petit sous-ensemble de documents.

Mise à jour:

Désolé, n'a pas remarqué la question est sur MySQL.

En MySQL, vous le faites de cette façon:

SELECT * 
FROM document d 
LEFT JOIN 
     version v 
ON  v.id = 
     (
     SELECT id 
     FROM version vi 
     WHERE vi.document = d.document 
     ORDER BY 
       vi.document DESC, vi.revision DESC, vi.id DESC 
     LIMIT 1 
     ) 

créer un index composite sur version (document, revision, id) pour que cela fonctionne rapidement.

+0

MySQL ne supporte pas 'APPLY' ou' ROW_NUMBER() '(fonctions de fenêtre). –

+0

@Bill: à droite, n'a pas remarqué qu'il s'agit de 'MySQL'. – Quassnoi

+0

La réponse ultérieure fonctionne mais si pour quelques lignes je n'ai qu'un seul enregistrement ex: la version n'a qu'un enregistrement pour un docID particulier dans ce cas, la requête ne récupère aucune ligne pour cet ID. Désolé pour la réponse tardive/commentaire –

0

Si je vous comprends bien, top ne résout pas non plus votre problème. top est exactement équivalent à limiter. Ce que vous cherchez, ce sont des fonctions agrégées, comme max() ou min() si vous voulez les extrêmes. par exemple:

select link_id, max(column_a), min(column_b) from table_a a, table_b b 
where a.link_id = b.link_id group by link_id