获取 5 条记录,按用户名排序,然后获取更多记录,直到在 MySQL 内达到 LIMIT 5

Get 5 records, sort by Username, then get more records until LIMIT 5 reached in MySQL

我正在尝试从 MySQL 数据库中提取 5 条最新记录,然后按 USER 将它们分组,然后在分组后获取更多记录,直到我有 5 条按日期排序的唯一 USER。理想情况下,我想通过一个查询来完成此操作。

数据库:

 -------------
| 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 个唯一记录,其中包含每个唯一用户的所有项目,如下所示:

 --------------------
| 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 |
 --------------------

这是否可以通过单个查询来完成,这样我就不必拉取记录、合并,然后再拉取更多记录?

我真的不明白为什么你需要这种奇怪的 selection,但这至少可以帮助你开始:

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;

两个子select 都获得了 5 个最新结果。然后从第一个我们得到 agrupation,从另一个我们得到用户排除。我们合并结果然后限制结果,因为我们不知道(我们知道,但不是更一般的情况)我们将在第一个 select.

上获得的结果数量

我想你可以在子查询上使用 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的子查询得到结果。

尝试以下查询

SELECT a.user , GROUP_CONCAT(a.item)
FROM ( select user , item from database 
GROUP BY user
ORDER BY date DESC LIMIT 5 ) as a;