我有一个表存储发送给用户的消息,布局如下
id (auto-incrementing) | message_id | user_id | datetime_sent
我正在尝试找到每个用户收到的第一个N message_id,但我完全被卡住了。我可以基于每个用户轻松完成(在查询中定义用户ID时),但不能用于所有用户。
注意事项:
编辑:第二个想法我删除了这一点,但已将其添加回去了,因为有人善于处理它
最终目标是查看有多少用户打开了他们收到的前N条消息之一。
这个打开的表看起来像这样:
user_id | message_id | datetime_opened
答案 0 :(得分:0)
这是对原始问题的未经测试的答案(前5个有2个表格和条件):
SELECT DISTINCT user_id
FROM (
SELECT om.user_id,
om.message_id,
count(DISTINCT sm2.message_id) messages_before
FROM opened_messages om
INNER JOIN sent_messages sm
ON om.user_id = sm.user_id
AND om.message_id = sm.message_id
LEFT JOIN sent_messages sm2
ON om.user_id = sm2.user_id
AND sm2.datetime_sent < sm.datetime_sent
GROUP BY om.user_id,
om.message_id
HAVING messages_before < 5
) AS base
子查询加入sm2
以计算发送给同一用户的先前消息的数量,然后having
子句确保发送的消息少于5个。对于同一用户,可能有多条消息(最多5条)具有该条件,外部查询仅列出符合条件的唯一用户。
答案 1 :(得分:0)
要获取前N个(此处为2条)消息,请尝试
var hunt = new RegExp(action.search);
var aSelector = document.getElementsByTagName('a');
var arr = Array.prototype.filter.call(aSelector, function(el){
return hunt.test(el.href)
});
for(var i=0; i<arr.length; i++){
var elem = arr[i].getAttribute('href');
elem.onclick = function(){
doStuff();
};
}
使用 RANK 替换,派生自@Seaux response到 mysql是否具有Oracle的“分析函数”?
要将其扩展到原始问题,只需添加适当的计算:
SELECT
user_id
, message_id
FROM (
SELECT
user_id
, message_id
, id
, (CASE WHEN @user_id != user_id THEN @rank := 1 ELSE @rank := @rank + 1 END) AS rank,
(CASE WHEN @user_id != user_id THEN @user_id := user_id ELSE @user_id END) AS _
FROM (SELECT * FROM MessageSent ORDER BY user_id, id) T
JOIN (SELECT @cnt := 0) c
JOIN (SELECT @user_id := 0) u
) R
WHERE rank < 3
ORDER BY user_id, id
;
在MySQL中没有CTE,并且在只读数据库中 - 我认为在语句中没有两次使用上述查询。
查看实际操作:SQL Fiddle。
请评论是否需要调整/进一步详细说明。