2009-09-29 6 views
1

Supposed I ont les tableaux suivants:requête SQL de trouver la ligne max à partir des moyennes agrégées

Sailor(sid, sname, age) 
Boat(bid, sid) 

Chaque bateau peut avoir de nombreux marins, et chaque marin individuel peut servir sur de nombreux bateaux. Ce que je veux faire est de trouver le bateau avec l'âge moyen le plus élevé des marins.

je peux trouver l'âge moyen du marin sur chaque bateau avec cette sous-requête:

SELECT b.bid, AVG(s.age) AS avg_age FROM sailor s, boat b 
WHERE b.sid = s.sid 
GROUP BY b.bid 

Cependant, je suis coincé sur la façon de trouver la ligne maximale de cette sous-requête plus loin.

P.S. Je suis également à la recherche d'une requête compatible MySQL, si cela fait une différence.

Répondre

2
SELECT t1.* 
FROM 
(SELECT b.bid, AVG(s.age) AS avg_age FROM sailor s, boat b 
    WHERE b.sid = s.sid 
    GROUP BY b.bid) t1 
LEFT OUTER JOIN 
(SELECT b.bid, AVG(s.age) AS avg_age FROM sailor s, boat b 
    WHERE b.sid = s.sid 
    GROUP BY b.bid) t2 
ON (t1.avg_age < t2.avg_age) 
WHERE t2.avg_age IS NULL; 
+0

+ 1 laid mais correct. Faire une requête séparée d'abord avec la suggestion de LIMIT de dnagirl peut être préférable à une sous-requête de cette complexité si elle n'est pas bouclée. Notez qu'il n'y a pas de rupture de lien avec des auto-null-jointures; Si deux bateaux ont le même âge moyen, deux lignes seront retournées. – bobince

+0

Oui, définitivement moche. En général, je n'aime pas faire «GROUP BY» dans une sous-requête. Yuck! –

+0

C'est la solution que je recherchais exactement. Même si ce n'est pas élégant et que la solution de @ dnagirl est préférable dans une situation réelle, j'aimerais comprendre comment la sous-requête SQL fonctionne dans ce cas. – ejel

1
SELECT b.bid, AVG(s.age) AS avg_age 
FROM sailor s JOIN boat b USING (sid) 
GROUP BY b.bid 
ORDER BY AVG(s.age) DESC 
LIMIT 1; 

Cela retournera une ligne, et en raison de la commande, il contiendra l'âge moyen maximum.

+0

Malheureusement LIMIT n'est pas disponible sur les sous-requêtes. – bobince

+0

MySQL le permet (peut-être involontairement) si vous le "double-sous-requête". Par exemple. '((SELECT ... LIMIT 1))' –

+0

J'ai lu la partie "sous-requête" de la question comme étant un hareng rouge. Il m'a semblé que ce qu'il veut, c'est «trouver le bateau avec l'âge moyen des marins le plus élevé». Donc oui, si la requête doit être une sous-requête, alors LIMIT est un problème sans l'imbrication @Bill Karwin suggère. – dnagirl

1

Dans le serveur sql il serait:

Select Top 1 Bid, Avg(age) 
    From boat b Join sailor s 
    On s.sid = b.sid 
    Group By Bid 
    Order By Avg(Age) Desc 

Je ne suis pas sur MySQL, mais il y a un mot-clé Linmit que « limites » la enumber de lignes retournées, si vous utilisez qu'au lieu de le Top 1, ça devrait marcher, non? Je ne suis pas exactement sûr de la syntaxe, mais ...

Select Bid, Avg(age) 
    From boat b Join sailor s 
    On s.sid = b.sid 
    Group By Bid 
    Order By Avg(Age) Desc 
    Limit 1 
Questions connexes