我正在尝试在GROUP BY中获取记录的子集,我已经看到了很多疯狂的解决方案,但它们看起来太复杂了,有没有更有效的方法来做到这一点。
SELECT user_id, GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items
FROM wb_user_book_current_item GROUP BY user_id
所以这将返回给我所有用户的所有当前项目,这是目前为止还可以。但我只想要十件最新的东西。将ORDER BY
添加到GROUP_CONCAT
会有所帮助,但它仍然没有给我最后十条记录。
修改
如果我做了这样的事情并硬编码user_id
那么我可以得到我想要的那个用户的结果,问题是将它组合起来,这样我就不需要硬编码{{1}例如,只需获得所有用户最后十项
user_id
答案 0 :(得分:5)
这是一个难题,但是这个怎么样:
SELECT user_id, GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items
FROM wb_user_book_current_item T
WHERE NOT EXISTS
(
SELECT 1
FROM wb_user_book_current_item T2
WHERE T2.user_id = T.user_id
ORDER BY T2.`timestamp` DESC
LIMIT 10,1
)
OR T.`timestamp` > (
SELECT T2.`timestamp`
FROM wb_user_book_current_item T2
WHERE T2.user_id = T.user_id
ORDER BY T2.`timestamp` DESC
LIMIT 10,1
)
GROUP BY user_id
这当然假设您不会为同一个用户提供两行timestamp
。
如果您的时间戳字段始终为正整数,您也可以将NOT EXISTS...OR
替换为COALESCE
:
SELECT user_id, GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items
FROM wb_user_book_current_item T
WHERE T.`timestamp` > COALESCE((
SELECT T2.`timestamp`
FROM wb_user_book_current_item T2
WHERE T2.user_id = T.user_id
ORDER BY T2.`timestamp` DESC
LIMIT 10,1
), 0)
GROUP BY user_id
原始答案,但显然MySQL并不了解如何正确执行此操作并抱怨subselect返回多行。当然我们想要多行;这是一个GROUP_CONCAT
。 GRR。
不幸的是,我认为使用子查询没有真正的方法:
SELECT T.user_id,
GROUP_CONCAT((SELECT T2.item_id
FROM wb_user_book_current_item T2
WHERE T2.user_id = T.user_id
ORDER BY T2.`timestamp`
LIMIT 10)) AS items
FROM wb_user_book_current_item T
GROUP BY user_id
否则,在其他任何地方添加LIMIT
将限制组的数量,或限制表中的总记录集(而不是组) - 这两者都不是您要实现的目标。
答案 1 :(得分:4)
所以在这里找到了一个很好的解决方案,效果非常好。
http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
这就是这样的事情:
SET @num := 0, @user_id := '';
SELECT cp2.user_id, CONCAT(cp2.item_id) AS items
FROM (
SELECT cp.user_id, cp.item_id,
@num := IF(@user_id = cp.user_id, @num + 1, 1) AS row_number,
@user_id := cp.user_id AS dummy
FROM wb_user_curent_item AS cp
ORDER BY cp.user_id ASC, cp.`timestamp` DESC
) AS cp2 WHERE cp2.row_number <= 10
GROUP BY cp2.user_id
所以基本上它只是使用num
增量来限制记录而不是使用LIMIT
答案 2 :(得分:1)
试试这个:
SELECT
user_id,
GROUP_CONCAT(item_id ORDER BY `timestamp`) AS items
FROM wb_user_book_current_item
GROUP BY user_id
LIMIT 0, 10
答案 3 :(得分:1)
SELECT
i.user_id,
GROUP_CONCAT(i.item_id ORDER BY i.timestamp) AS items
FROM
( SELECT DISTINCT user_id
FROM wb_user_book_current_item
) AS du
JOIN
wb_user_book_current_item AS i
ON i.user_id = du.user_id
AND i.timestamp <= COALESCE(
( SELECT i2.item_id
FROM wb_user_book_current_item AS i2
WHERE i2.user_id = du.user_id
ORDER BY i2.timestamp ASC
LIMIT 1 OFFSET 9
)
, '2038-01-19 03:14:07')
GROUP BY
i.user_id ;
(user_id, timestamp, item_id)
上的索引有助于提高效率。
答案 4 :(得分:0)
更新:我没有注意到GROUP_CONCAT,所以你必须在LIMIT中使用子查询
使用LIMIT
SELECT column_name(s)
FROM table_name
LIMIT number