SQL查询帮助 - 每个不同列值的10条记录

时间:2011-08-16 07:15:54

标签: mysql sql greatest-n-per-group

我有一张包含汽车清单的汽车表。 表结构类似于:

 cars
   - id
   - title
   - make
   - year

我想要一个返回每个品牌10辆汽车的查询。

等同于以下伪代码的东西:

car_makes = select distinct make from cars
for each make in car_makes 
  select id, title, make from clcars where make = $make limit 10;
end

这是我尝试过的失败:

select id,title,make 
from cars where make in 
                    (select distinct make from cars) 
group by make;

---每次只返回一条记录。

select a.id,a.title,a.make 
from cars a left join  
 (select distinct make from cars) car_make 
   on a.make = car_make.make;

返回每条记录。

每辆车只需要10条记录。

感谢您的帮助

2 个答案:

答案 0 :(得分:3)

这会给你你想要的东西:

set @prev := '', @i := 0;
select  make, id, title, year
from (select id, title, make, year, (@i := if(@prev = make, @i + 1, 0)) as idx, (@prev := make)
from (select id, title, make, year from cars order by make, id) ordered) indexed
where idx < 10

要更改要获取的 10行的选择,请更改最内层查询的顺序;我选择了身份order by make, id,但您可以选择年份。只要make是第一个,它就会起作用。你可以为“随机”选择留下任何其他东西。 根据需要订购最终结果。

这是如何运作的:

  • 最里面的查询只是命令准备编号的行 - 别名为ordered
  • 下一个包装器查询计算make组中的行号(@i - 从零开始计数) - 别名为indexed@prev持有前一行的品牌
  • 外部查询从indexed中选择行号小于10的数据

这是测试代码,边缘情况为1 bmw,3 gmc和13个fords:

create table cars (id int not null primary key auto_increment, title text, make text, year text);
insert into cars (title, make, year) values 
('f1', 'ford', 2000), ('f2', 'ford', 2001), ('f3', 'ford', 2002), ('f4', 'ford', 2003),
('f5', 'ford', 2004), ('f6', 'ford', 2005), ('f7', 'ford', 2006), ('f8', 'ford', 2007),
('f9', 'ford', 2008), ('f10', 'ford', 2009), ('f11', 'ford', 2010), ('f12', 'ford', 2011),
('f13', 'ford', 2012), ('g1', 'gmc', 2000), ('g2', 'gmc', 2001), ('g3', 'gmc', 2002), 
('b1', 'bmw', 2002);

以上查询的输出:

+------+----+-------+------+
| make | id | title | year |
+------+----+-------+------+
| bmw  | 17 | b1    | 2002 |
| ford |  1 | f1    | 2000 |
| ford |  2 | f2    | 2001 |
| ford |  3 | f3    | 2002 |
| ford |  4 | f4    | 2003 |
| ford |  5 | f5    | 2004 |
| ford |  6 | f6    | 2005 |
| ford |  7 | f7    | 2006 |
| ford |  8 | f8    | 2007 |
| ford |  9 | f9    | 2008 |
| ford | 10 | f10   | 2009 |
| gmc  | 14 | g1    | 2000 |
| gmc  | 15 | g2    | 2001 |
| gmc  | 16 | g3    | 2002 |
+------+----+-------+------+

答案 1 :(得分:1)

您似乎可以使用存储过程和游标执行此操作。 有关详细信息,请参阅http://dev.mysql.com/doc/refman/5.0/en/cursors.html