Каков наилучший способ выбрать первые две записи каждой группы командой «SELECT»?

Например, у меня есть следующая таблица:

id group data 1 1 aaa 2 1 aaa 3 2 aaa 4 2 aaa 5 2 aaa 6 3 aaa 7 3 aaa 8 3 aaa 

Каков наилучший способ выбрать первые две записи каждой группы командой «SELECT»? Если нет хорошего способа сделать это, какую рутину вы предлагаете? (В PHP)

(результат модели)

 1 1 aaa 2 1 aaa 3 2 aaa 4 2 aaa 6 3 aaa 7 3 aaa 

Я знал, что перекрестное соединение a.id> = b.id в подзапросе может работать, но я ищу более масштабируемое решение, которое можно применить к таблице с миллионами записей. благодаря

Related of "Каков наилучший способ выбрать первые две записи каждой группы командой «SELECT»?"

 select a.* from Tablename a where ( select count(*) from Tablename as b where a.group = b.group and a.id >= b.id ) <= 2 
  • Демоверсия SQLFiddle

Мне нравится этот трюк, который использует функцию агрегации GROUP_CONCAT и FIND_IN_SET:

 SELECT Tablename.* FROM Tablename INNER JOIN ( SELECT `group`, GROUP_CONCAT(id ORDER BY id) ids FROM Tablename GROUP BY `group`) grp ON Tablename.`group` = grp.`group` AND FIND_IN_SET(Tablename.id, ids)<=2 ORDER BY Tablename.`group`, Tablename.id 

Выступления не могут быть слишком хорошими, поскольку они не могут использовать индекс.

Или вы также можете использовать это:

 SELECT t1.id, t1.`group`, t1.data from Tablename t1 INNER JOIN Tablename t2 ON t1.`group` = t2.`group` AND t1.id>=t2.id GROUP BY t1.id, t1.`group`, t1.data HAVING COUNT(*)<=2 ORDER BY t1.`group`, t1.id, t1.data 

Вы выбираете, фильтруете и заказываете свой запрос, как обычно, а затем

для MSSQL

 SELECT TOP 2 * FROM foo; 

Из того, что я могу вспомнить Sybase , Oracle и, возможно, некоторые другие RDBMS использует этот синтаксис.

для MySQL вы делаете

 SELECT * FROM foo LIMIT 2; 

Обновить:

Да, я неправильно понял ваш вопрос, извините. Кажется, что некоторые из нас сделали 🙂

Тогда это зависит от того, поддерживает ли RDBMS HAVING или нет. Вы могли бы построить запрос, используя HAVING или используя IN и подзапрос в предложении IN .

Для MSSQL я думаю, что вы могли бы сделать что-то вроде (код не тестировался)

 SELECT id, data FROM ( SELECT id, data, Rank() over (Partition BY group ORDER BY id DESC ) AS Rank FROM table ) rs WHERE Rank <= 2) 

Но так как это зависит от ваших СУБД, я прошу вас посмотреть на подобные вопросы и посмотреть, какой из них лучше всего подходит для вашего дела, поскольку MSSQL поддерживает некоторые вещи, которые MySQL не делает и наоборот.

вот несколько примеров

Выберите 10 лучших записей для каждой категории

Как выбрать последние две записи для каждого topic_id в MySQL