如何连接MYSQL组中前N条记录的查询结果
How to concat query result of top N records from a group in MYSQL
我有以下查询,它给出了按降序排列的用户 ID 分组的名称的计数。到目前为止,我已经达到了,但不能超越。我想连接每个用户前 2 条记录的名称列。
目前的查询是:
SELECT t.*,
IF(@grp = t.user_id, @rowno := @rowno + 1, @rowno := 1) AS rowno,
@grp := t.user_id AS u_id
FROM (SELECT notes.user_id,
t.name name,
Count(t.name) ct
FROM notes
INNER JOIN tags t
ON notes.id = t.note_id
GROUP BY notes.user_id,
t.name
ORDER BY notes.user_id,
Count(t.name) DESC) t;
结果如下:
+---------+------------+----+-------+-----+
| user_id | name | ct | rowno | uid |
+---------+------------+----+-------+-----+
| 282 | realifex | 1 | 1 | 282 |
+---------+------------+----+-------+-----+
| 282 | clear | 1 | 2 | 282 |
+---------+------------+----+-------+-----+
| 282 | thinking | 1 | 3 | 282 |
+---------+------------+----+-------+-----+
| 282 | refreshing | 1 | 4 | 282 |
+---------+------------+----+-------+-----+
| 285 | solid | 2 | 1 | 285 |
+---------+------------+----+-------+-----+
| 285 | clear | 1 | 2 | 285 |
+---------+------------+----+-------+-----+
| 285 | thinking | 1 | 3 | 285 |
+---------+------------+----+-------+-----+
| 287 | holidays | 3 | 1 | 287 |
+---------+------------+----+-------+-----+
| 287 | Larry | 3 | 2 | 287 |
+---------+------------+----+-------+-----+
| 287 | travel | 2 | 3 | 287 |
+---------+------------+----+-------+-----+
| 287 | thinking | 1 | 4 | 287 |
+---------+------------+----+-------+-----+
我正在尝试将每个用户组的前 2 个结果合并到一列中,如下所示:
+---------+----------------+
| user_id | name |
+---------+----------------+
| 282 | realifex,clear |
+---------+----------------+
| 285 | solid, clear |
+---------+----------------+
| 287 | Larry,travel |
+---------+----------------+
我们 group_concat()
:
SELECT group_id, group_concat(name order by rn) as names
FROM (SELECT t.*,
(@rn := IF(@grp = t.user_id, @rowno := @rowno + 1,
IF(@grp := t.user_id, 1, 1)
)
) as rn
FROM (SELECT n.user_id, t.name, n.name, Count(t.name) ct
FROM notes n INNER JOIN
tags t
ON notes.id = t.note_id
GROUP BY n.user_id, t.name
ORDER BY n.user_id, Count(t.name) DESC
) t CROSS JOIN
(SELECT @rn := 0, @grp := -1) params
) t
WHERE rn <= 2
GROUP BY user_id;
注:
@rn
和 @grp
的表达式是单个表达式。 MySQL 不保证 SELECT
中表达式的求值顺序,因此单个表达式是安全分配两个变量的唯一方法。
- 变量已初始化。
WHERE
子句是确定 "top 2" 的地方。
我有以下查询,它给出了按降序排列的用户 ID 分组的名称的计数。到目前为止,我已经达到了,但不能超越。我想连接每个用户前 2 条记录的名称列。
目前的查询是:
SELECT t.*,
IF(@grp = t.user_id, @rowno := @rowno + 1, @rowno := 1) AS rowno,
@grp := t.user_id AS u_id
FROM (SELECT notes.user_id,
t.name name,
Count(t.name) ct
FROM notes
INNER JOIN tags t
ON notes.id = t.note_id
GROUP BY notes.user_id,
t.name
ORDER BY notes.user_id,
Count(t.name) DESC) t;
结果如下:
+---------+------------+----+-------+-----+
| user_id | name | ct | rowno | uid |
+---------+------------+----+-------+-----+
| 282 | realifex | 1 | 1 | 282 |
+---------+------------+----+-------+-----+
| 282 | clear | 1 | 2 | 282 |
+---------+------------+----+-------+-----+
| 282 | thinking | 1 | 3 | 282 |
+---------+------------+----+-------+-----+
| 282 | refreshing | 1 | 4 | 282 |
+---------+------------+----+-------+-----+
| 285 | solid | 2 | 1 | 285 |
+---------+------------+----+-------+-----+
| 285 | clear | 1 | 2 | 285 |
+---------+------------+----+-------+-----+
| 285 | thinking | 1 | 3 | 285 |
+---------+------------+----+-------+-----+
| 287 | holidays | 3 | 1 | 287 |
+---------+------------+----+-------+-----+
| 287 | Larry | 3 | 2 | 287 |
+---------+------------+----+-------+-----+
| 287 | travel | 2 | 3 | 287 |
+---------+------------+----+-------+-----+
| 287 | thinking | 1 | 4 | 287 |
+---------+------------+----+-------+-----+
我正在尝试将每个用户组的前 2 个结果合并到一列中,如下所示:
+---------+----------------+
| user_id | name |
+---------+----------------+
| 282 | realifex,clear |
+---------+----------------+
| 285 | solid, clear |
+---------+----------------+
| 287 | Larry,travel |
+---------+----------------+
我们 group_concat()
:
SELECT group_id, group_concat(name order by rn) as names
FROM (SELECT t.*,
(@rn := IF(@grp = t.user_id, @rowno := @rowno + 1,
IF(@grp := t.user_id, 1, 1)
)
) as rn
FROM (SELECT n.user_id, t.name, n.name, Count(t.name) ct
FROM notes n INNER JOIN
tags t
ON notes.id = t.note_id
GROUP BY n.user_id, t.name
ORDER BY n.user_id, Count(t.name) DESC
) t CROSS JOIN
(SELECT @rn := 0, @grp := -1) params
) t
WHERE rn <= 2
GROUP BY user_id;
注:
@rn
和@grp
的表达式是单个表达式。 MySQL 不保证SELECT
中表达式的求值顺序,因此单个表达式是安全分配两个变量的唯一方法。- 变量已初始化。
WHERE
子句是确定 "top 2" 的地方。