SQL Query help - 10 records for each distinct column value

守給你的承諾、 提交于 2020-01-13 04:50:11

问题


I have a cars table which contains car listings. The table structure looks something like:

 cars
   - id
   - title
   - make
   - year

I would like a query which returns 10 cars of each make.

Something equivalent to the following pseudo code:

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

Here's what I've tried unsuccessfully:

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

--- This returns only one record per 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;

This returns every record.

I need only 10 records per car make.

Thanks for your help


回答1:


This will give you what you want:

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

To alter the choice of which 10 rows to get, change the order by of the inner-most query; I chose id order by make, id, but you could choose year. As long as make is first it will work. You could leave off anything else for a "random" pick. Order the final result as you wish.

How this works:

  • The inner-most query simply orders the rows ready for numbering - aliased as ordered
  • The next wrapper query calculates the row number (@i - counting from zero) within the make group - aliased as indexed. @prev holds the make from the previous row
  • The outer query selects data from indexed where the row number is less than 10

Here's the test code, with edge cases of 1 bmw, 3 gmc and 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);

Output from above query:

+------+----+-------+------+
| 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 |
+------+----+-------+------+



回答2:


It seems that you can do it using stored procedure and cursors. See http://dev.mysql.com/doc/refman/5.0/en/cursors.html for more info



来源:https://stackoverflow.com/questions/7074750/sql-query-help-10-records-for-each-distinct-column-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!