2010-11-08 10 views
2

Lorsque je rejoins intérieurement la deuxième table, je veux seulement joindre une seule ligne. Le critère consiste à prendre la ligne avec l'entier le plus élevé dans la colonne de niveau. Je pensais quelque chose comme ceci:Inner joindre une seule ligne en obtenant seulement la plus haute ligne entière

SELECT * 
FROM file_repo 
INNER JOIN 
( SELECT 
     MAX(files.level) 
    FROM 
     files 
) ON file_repo.id = files.repo_id 

Pour chaque ligne de file_repo je vais obtenir une seule rangée de fichiers avec la valeur la plus élevée dans la colonne de niveau.

Répondre

5
SELECT * 
FROM file_repo fr 
JOIN files f 
ON  f.id = 
     (
     SELECT id 
     FROM files fi 
     WHERE fi.repo_id = fr.id 
     ORDER BY 
       repo_id DESC, level DESC, id DESC 
     LIMIT 1 
     ) 

Créer un index sur files (repo_id, level, id) pour que cela fonctionne rapidement.

Ceci traitera correctement les doublons sur level.

+0

Cette solution semble fonctionner plutôt lentement par rapport à l'autre (10x environ). Quel est le problème qui se produit lorsque deux file_repo partagent le même niveau dans l'autre exemple? Est-ce juste un choix incohérent de fichier correspondant? –

+0

@ebyrob: vous obtiendrez tous les derniers fichiers au lieu d'un. Notez que les performances dépendent de la façon dont les tables sont indexées, et l'autre solution peut être plus rapide si vous avez beaucoup de repos vides (sans aucun fichier). – Quassnoi

5
SELECT fr.*, fm.MaxLevel 
FROM file_repo fr 
INNER JOIN ( 
    SELECT repo_id, MAX(level) as MaxLevel 
    FROM files 
    GROUP BY repo_id 
) fm ON fr.id = fm.repo_id 
Questions connexes