Например, у меня есть следующая таблица:
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 в подзапросе может работать, но я ищу более масштабируемое решение, которое можно применить к таблице с миллионами записей. благодаря
select a.* from Tablename a where ( select count(*) from Tablename as b where a.group = b.group and a.id >= b.id ) <= 2
Мне нравится этот трюк, который использует функцию агрегации 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