选择max()和其他字段

时间:2013-02-14 19:49:32

标签: mysql

我们有一张桌子:

create table ducks (id int(8) primary key not null auto_increment,
                    name varchar(255),
                    car varchar(255), 
                    money int(8)
                   );
insert into ducks set name='donald', car='none', money=10;
insert into ducks set name='scrudge', car='bip', money=10000;
insert into ducks set name='mac', car='bip', money=1000;
insert into ducks set name='joe', car='boo', money=2000000;

所以分析这个我发现我们对以下请求的查询很慢:

select name,money from ducks where car='bip' order by money DESC LIMIT 1;

因为表很大而且排序只是为了得到一条记录很长

我发现以下内容更快:

select distinct name,money from ducks where money=(select max(money) from ducks where car='bip')  LIMIT 1;

但仍然不确定,因为它是子选择。

解决这个问题的常用方法是什么?

http://sqlfiddle.com/#!2/d2b7ed/6

更新它转变为现实中我们的任务是不搜索同一辆车,但搜索价格低于100000美元的最富有的鸭子

http://sqlfiddle.com/#!2/d2b7ed/21

1 个答案:

答案 0 :(得分:1)

你明智地要警惕子查询;特别是在MySQL中。

以下查询使用自我排除联接,并且在基本测试中执行三者中最好的一个。你的第一个解决方案很好,但正如你说的慢。它也不符合ANSI标准,但这对您来说无关紧要。你的第二个解决方案也没问题,但是MySQL并没有像希望的那样处理子查询;至少传统上。

select 
  d.name, d.money
from 
  ducks d
  left join ducks d2 
  on d2.car = d.car 
  and d2.money > d.money
where 
  d.car = 'bip'
  and d2.id is null

在这里实施:http://sqlfiddle.com/#!2/27711/20


编辑:球门柱以某种方式移动了。弄清楚那些球门柱。这是针对新问题的自我排除加入解决方案:http://sqlfiddle.com/#!2/7146d/13

select 
  d.name, d.money 
from 
  ducks d
  left join ducks d2 
  on d2.money > d.money
  and d2.money < 100000
where 
  d.money < 100000 
  and d2.id is null;