我正在为我们的网站构建一个事件流,并且在一些运行良好的东西上取得了不错的进展。
它由两个表提供支持:
流:
id
- 唯一的流项目 IDuser_id
- 创建流项目的用户 IDobject_type
- 对象类型(当前为“卖家”或“产品”)object_id
- 对象的内部 ID(当前为卖家 ID 或产品 ID)action_name
- 对对象执行的操作(当前为“购买”或“心”)stream_date
- 创建操作的时间戳。hidden
- 用户是否选择隐藏项目的 bool 值。
关注:
id
- 唯一的关注 IDuser_id
- 发起“关注”操作的用户 ID。following_user
- 被关注用户的 ID。followed
- 执行后续操作的时间戳。
目前我正在使用以下查询从数据库中提取内容:
查询:
SELECT stream.*,
COUNT(stream.id) AS rows_in_group,
GROUP_CONCAT(stream.id) AS in_collection
FROM stream
INNER JOIN follows ON stream.user_id = follows.following_user
WHERE follows.user_id = '1'
AND stream.hidden = '0'
GROUP BY stream.user_id,
stream.action_name,
stream.object_type,
date(stream.stream_date)
ORDER BY stream.stream_date DESC;
这个查询实际上工作得很好,并且使用一点 PHP 来解析 MySQL 返回的数据,我们可以创建一个很好的事件流,如果操作之间的时间不是,则同一用户的相同类型的操作被分组在一起。 t 太大了(见下面的例子)。
我的问题是,我怎样才能让它更智能?目前它按一个轴“用户”事件分组,当特定用户在特定时间范围内有多个项目时,MySQL 知道将它们分组。
我怎样才能使它更智能并按另一个轴分组,例如“object_id”,所以如果按顺序对同一对象有多个操作,这些项目将被分组,但保持我们当前用于分组操作的分组逻辑/用户的对象。并在没有数据重复的情况下实现这一点?
多个对象依次出现的例子:
我了解此类问题的解决方案可能会变得非常复杂、非常迅速,但我想知道在 MySQL 中是否有一个优雅且相当简单的解决方案(希望如此)。
最佳答案
关于您想要的结果的一些观察:
有些元素是汇总的( jack 斯普拉特喜欢七个卖家),而其他元素是逐项列出的(纳尔逊勋爵租用了金鹿)。您可能需要在查询中使用 UNION 将这两类项目从两个单独的子查询中提取出来。
您使用一个相当粗略的时间戳接近函数来对您的项目进行分组... DATE()
。您可能想要使用更复杂和可调整的方案...像这样,也许
GROUP BY TIMESTAMPDIFF(HOUR,CURRENT_TIME(),stream_date) DIV hourchunk
这将使您可以按年龄组对内容进行分组。例如,如果您将 48 用于 hourchunk
,您会将 0-48 小时前的内容组合在一起。当您向系统添加流量和操作时,您可能希望减小 hourchunk
值。
关于php - 事件流的智能 MySQL GROUP BY,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14004322/