Это даст вам то, что вы хотите:
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 |
+------+----+-------+------+