Справка по SQL-запросу - 10 записей для каждого отдельного значения столбца - PullRequest
3 голосов
/ 16 августа 2011

У меня есть таблица автомобилей, которая содержит списки автомобилей.Структура таблицы выглядит примерно так:

 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 ]

3 голосов
/ 16 августа 2011

Это даст вам то, что вы хотите:

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 строк, измените порядок самого внутреннего запроса; Я выбрал id order by make, id, но вы можете выбрать год. Пока make первый, он будет работать. Вы можете оставить все что угодно для «случайного» выбора. Закажите конечный результат по вашему желанию.

Как это работает:

  • Самый внутренний запрос просто упорядочивает строки, готовые к нумерации - с псевдонимом ordered
  • В следующем запросе оболочки вычисляется номер строки (@i - считая с нуля) внутри группы make - с псевдонимом indexed. @prev содержит марку из предыдущего ряда
  • Внешний запрос выбирает данные из indexed, где номер строки меньше 10

Вот тестовый код с краями 1 бмв, 3 гмц и 13 бродами:

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 голос
/ 16 августа 2011

Кажется, что вы можете сделать это, используя хранимые процедуры и курсоры.См. http://dev.mysql.com/doc/refman/5.0/en/cursors.html для получения дополнительной информации

...