2009-09-29 37 views
1

找到最大行:SQL查询从假设我有以下表格汇总平均

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

每艘船可以有很多水手,和每一个人的水手可以担任许多船只。我想要做的是找到水手平均年龄最高的船。

我能找到的水手对每艘船的平均年龄与此子查询:

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

不过,我被困在如何找到这个子查询中的最大行进一步上。

P.S.我也在寻找与MySQL兼容的查询,如果这有什么不同。

回答

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难看但正确。首先用dnagirl的LIMIT建议做一个单独的查询可能比这个复杂的子查询更可取,如果它没有循环的话。请注意,与自我无效连接没有平局;如果两艘船碰巧有相同的平均年龄,则会返回两排船。 – bobince 2009-09-29 01:07:18

+0

是的,绝对丑陋。我通常不喜欢在子查询中执行“GROUP BY”。呸! – 2009-09-29 01:09:55

+0

这是我正在寻找的解决方案。尽管它并不优雅,并且@ dnagirl的解决方案在实际情况下可能更可取,但我想了解SQL子查询在这种情况下是如何工作的。 – ejel 2009-09-29 17:13:16

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; 

这将返回一行,并且由于排序它将包含最大平均年龄。

+0

不幸的是LIMIT在子查询上不可用。 – bobince 2009-09-29 01:03:42

+0

如果您“双重子查询”,MySQL确实会允许它(可能是无意)。例如。 '((SELECT ... LIMIT 1))' – 2009-09-29 01:09:07

+0

我把这个问题的“子查询”部分读为红鲱鱼。在我看来,他想要的是“找到水手平均年龄最高的船”。所以是的,如果查询必须是子查询,那么LIMIT是没有嵌套的问题@Bill Karwin所建议的。 – dnagirl 2009-09-29 01:14:25

1

在SQL Server中这将是:

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 

我不能起来MySQL的,但有一个Linmit关键词是“限”行enumber回来,如果你用这个来代替顶1,它应该工作,不是?我不太确定语法,但是...

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