лимит mysql внутри группы? - PullRequest
5 голосов
/ 20 июля 2009

Я хочу ограничить размер записей внутри группы, и вот моя пробная версия, как это сделать правильно?

mysql> select * from accounts limit 5 group by type;

ОШИБКА 1064 (42000): у вас ошибка в синтаксисе SQL; проверить руководство что соответствует вашей версии сервера MySQL для правильный синтаксис для использования рядом с 'group by type' в строке 1

Ответы [ 8 ]

5 голосов
/ 20 июля 2009

Задача агрегатной функции (и необходимой ей GROUP BY) состоит в том, чтобы превратить много строк в одну строку. Так что, если вы действительно хотите получить 5 лучших сберегательных счетов и 5 лучших чековых счетов, 5 лучших долларовых счетов и т. Д., То вам нужно больше:

критерий: топ-5 определенного типа счета по account_balance

SELECT account_type, account_balance FROM accounts WHERE account_type='savings' 
   ORDER BY account_balance DESC LIMIT 5
UNION
SELECT account_type, account_balance FROM accounts WHERE account_type='chequing' 
   ORDER BY account_balance DESC LIMIT 5
UNION
SELECT account_type, account_balance FROM accounts WHERE account_type='USD' 
   ORDER BY account_balance DESC LIMIT 5;

Это не красиво, но если вы создаете SQL с помощью скрипта, тогда вставка в account_types и объединение запроса в запрос выполняется просто.

5 голосов
/ 17 августа 2012

Мне повезло с использованием пронумерованных строк:

set @type = '';
set @num = 0;

select
  items.*,
  @num := if(@type = item_type, @num + 1, 1) as dummy_1,
  @type := item_type as dummy_2,
  @num as row_number
from items
group by
  item_type,
  row_number
having row_number < 3;

Это даст вам 2 результата за item_type. (Один вопрос: убедитесь, что вы повторно запустили первые два оператора set, в противном случае номера строк будут постоянно увеличиваться и увеличиваться, а ограничение row_number < 3 не будет работать.

Я сложил это из пары сообщений , которые были связаны в других ответах на SO.

1 голос
/ 20 июля 2009

Похоже, вы хотите ограничить количество строк, возвращаемых в каждой группе вашего общего набора результатов ... это трудно сделать способом, который хорошо масштабируется. Один из способов - выполнить N объединений в одной и той же таблице с такими условиями, чтобы единственными подходящими строками были требуемый верхний / нижний N.

эта страница может дать дополнительное представление о вашем решении ... хотя возвращение топ-5 в каждой группе будет ужасно быстрым.

1 голос
/ 20 июля 2009

Попробуйте поместить предложение LIMIT после предложения GROUP BY.

РЕДАКТИРОВАТЬ: Попробуйте это:

SELECT * 
FROM accounts a1
WHERE 5 > 
(
   SELECT COUNT(*)
   FROM accounts a2
   WHERE a2.type = a1.type
   AND a2.balance > a1.balance
)

Возвращает не более 5 учетных записей каждого типа с наибольшим балансом.

0 голосов
/ 17 июня 2013

@ Ответ dnagirl почти имеет его, но по какой-то причине моя версия MySQL возвращает только первый установленный LIMIT. Чтобы обойти это, я помещаю каждое утверждение в подзапрос

SELECT * FROM (
    SELECT account_type, account_balance FROM accounts WHERE account_type='savings' 
       ORDER BY account_balance DESC LIMIT 5
) as a
UNION
SELECT* FROM (
    SELECT account_type, account_balance FROM accounts WHERE account_type='chequing' 
       ORDER BY account_balance DESC LIMIT 5
) as b
UNION
SELECT * FROM (
    SELECT account_type, account_balance FROM accounts WHERE account_type='USD' 
       ORDER BY account_balance DESC LIMIT 5
) as c

Это вернуло мне результаты каждого набора в окончательном наборе результатов. В противном случае я получил бы только первые 5 из первого запроса и ничего больше - не уверен, что это просто фанк MySQL с моей версией

0 голосов
/ 20 июля 2009

Это, вероятно, сделает свое дело, хотя если type не проиндексировано, это будет sloooowwww . И даже с одним это не особенно быстро:

SELECT a.*
FROM accounts a
     LEFT JOIN accounts a2 ON (a2.type = a.type AND a2.id < a.id)
WHERE count(a2.id) < 5
GROUP BY a.id;

Лучше было бы просто order список на type, а затем использовать цикл на бизнес-уровне для удаления ненужных строк.

0 голосов
/ 20 июля 2009

Я не уверен, что вы можете использовать лимит в группе по. Вы, вероятно, можете использовать его, если ваша группа является подвыбором, который возвращает одну строку / значение. Например:

выберите * из порядка foo (выберите foo2.id из предела 1 foo2)

Я просто предполагаю, что это сработает.

0 голосов
/ 20 июля 2009

Группировка по используется для агрегатных функций (суммы, средние значения ...)

Is позволяет разделить совокупный результат на группы. Вы не использовали ни одну из этих функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...