Получите 5 записей, отсортируйте по имени пользователя, затем получите больше записей, пока LIMIT 5 не достигнет в MySQL - PullRequest
0 голосов
/ 27 марта 2019

Я пытаюсь извлечь 5 самых последних записей из базы данных MySQL, затем сгруппировать их по USER, затем, после их группировки, получить больше записей, пока у меня не будет 5 уникальных пользователей, упорядоченных по дате.В идеале я хотел бы сделать это одним запросом.

База данных:

 -------------
| user | item |
 -------------
|    1 |  aaa |
|    3 |  bbb |
|    1 |  ccc |
|    2 |  ddd |
|    3 |  iii |
|    4 |  eee |
|    6 |  fff |
|    5 |  ggg |
|    1 |  hhh |
 -------------

Сейчас у меня есть этот запрос:

SELECT user,GROUP_CONCAT(item)
FROM database
GROUP BY user
ORDER BY date DESC
LIMIT 5

Но это дает мне 5 уникальных записей со ВСЕМИ элементами для каждого уникального ПОЛЬЗОВАТЕЛЯ, напримерthis:

 --------------------
| user |       items |
 --------------------
|    1 | aaa,ccc,hhh |
|    3 |     bbb,iii |
|    2 |         ddd |
|    4 |         eee |
|    6 |         fff |
 --------------------

В предыдущем примере у пользователя 1 не должно быть элемента "hhh", потому что перед этой записью находится 7 записей с 5 уникальными ПОЛЬЗОВАТЕЛЯМИ.Вместо этого я хочу получить первые 5 записей (оканчивающиеся на USER 3 iii), затем группировать дубликаты записей пользователя 1 и пользователя 3, а затем получить еще две записи для достижения LIMIT 5, например:

 --------------------
| user |       items |
 --------------------
|    1 |     aaa,ccc |
|    3 |     bbb,iii |
|    2 |         ddd |
|    4 |         eee |
|    6 |         fff |
 --------------------

Можно ли это сделать с помощью одного запроса, чтобы мне не приходилось извлекать записи, объединять, а затем извлекать больше записей?

Ответы [ 3 ]

0 голосов
/ 27 марта 2019

Я думаю, вы можете использовать row_number() over(partition_by user) AS user_occurence_num для подзапроса, который даст вам:

 --------------------------------
| user | item |user_occurence_num|
|------|------|------------------|
|    1 |  aaa |1                 |
|      |      |                  |    
|    3 |  bbb |1                 |
|      |      |                  |
|    1 |  ccc |2                 |   
|    2 |  ddd |1                 |    
|    3 |  iii |2                 |  
|    4 |  eee |1                 |
|      |      |                  |
|    6 |  fff |1                 | 
|      |      |                  |
|    5 |  ggg |1                 |
|      |      |                  |
|    1 |  hhh |3                 |   
 ---------------------------------

, а затем отфильтровать подзапрос, где user_occurence_num = 1 LIMIT 5, чтобы получить результат.

0 голосов
/ 27 марта 2019

Попробуйте запрос ниже

SELECT a.user , GROUP_CONCAT(a.item)
FROM ( select user , item from database 
GROUP BY user
ORDER BY date DESC LIMIT 5 ) as a;
0 голосов
/ 27 марта 2019

Я действительно не понимаю, зачем вам нужен такой странный выбор, но это может помочь вам, по крайней мере, начать с:

SELECT u.user, u.item FROM
(SELECT db.user, group_concat(db.item) as item
FROM ( 
    SELECT user, item 
    FROM database  
    ORDER BY date DESC 
    LIMIT 5 
) db
UNION
SELECT user, item
FROM database 
WHERE user not in ( 
    SELECT user
    FROM database  
    ORDER BY date DESC 
    LIMIT 5 
) db
ORDER BY date DESC
limit 5) u
LIMIT 5;

Оба подвыбора получают 5 последних результатов. Затем из первого мы получаем агрегацию, а из другого мы исключаем пользователей. Мы объединяем результаты и затем ограничиваем результаты, поскольку мы не знаем (мы знаем, но не для более общего случая) количество результатов, которые мы собираемся получить при первом выборе.

...