我有一个表格,可以跟踪每个用户相对于每个帖子的活动:
CREATE TABLE users2posts (
uts int unsigned not null comment 'uts for Unix Time Stamp',
user_id int unsigned not null,
post_id int unsigned not null,
action set('follow','unfollow','upvote','downvote'),
PRIMARY KEY (uts,user_id,post_id)
);
我想获取当前关注给定帖子的所有用户的ID。这转化为获取最后“跟随”或“取消关注”操作“跟随”的所有用户的ID。我想出的是:
SELECT user_id, action
FROM users2posts
WHERE post_id=1
AND (action="follow" OR action="unfollow")
GROUP BY user_id
ORDER BY uts DESC;
然后我循环遍历所有结果并存储那些最后一步操作的人员的ID:
foreach ($ROWS as $ROW)
if ($ROW['action'] == 'follow')
$FOLLOWERS[] = $ROW['user_id'];
但是,这不起作用。它存储用户的ID,其最后一个操作是取消关注帖子。我哪里错了?提前谢谢。
更新
我认为问题来自MySQL查询。其背后的想法是选择跟随或取消关注帖子的所有用户,然后按日期排序,并使用GROUP BY子句将选择缩减为每个用户执行的最后操作。但是,查询似乎是在订购之前进行分组。它应该发生什么?我该如何解决?
答案 0 :(得分:1)
将MAX()
用于uts
列,因为它包含时间戳。虽然您使用的是int
类型,但建议使用datetime
。
SELECT
MAX(uts) `last_action_time`, -- max time is the most recent time
user_id ,
action
FROM
users2posts
WHERE
action='follow' -- only track the follow action
GROUP BY
user_id,
action -- if you omit action from here last action will be calculated
-- from both follow and unfolllow
ORDER BY
uts
DESC;
答案 1 :(得分:1)
select *
from users2posts
where uts in
(
select max(uts) as lastaction
from users2posts
where post_id=1
group by user_id
)
and action = 'follow'
子选择将获取帖子1的每个用户的最后一个动作(如果有的话),主查询只获得那些实际上是follow
的动作。
答案 2 :(得分:1)
无需在PHP中处理它。您可以要求DBMS为您执行此操作:
select up1.user_id from users2posts up1
left join (
select up3.user_id, up3.post_id, up3.uts from users2posts up3
where up3.action in ('follow', 'unfollow')
) as up2
on up1.user_id = up2.user_id and up1.post_id = up2.post_id and up1.uts < up2.uts
where up1.action = 'follow' and up2.user_id is null and up1.post_id = 1
鉴于以下数据:
+------------+---------+---------+----------+
| UTS | USER_ID | POST_ID | ACTION |
+------------+---------+---------+----------+
| 2000-01-01 | 1 | 1 | follow |
| 2001-01-01 | 1 | 1 | unfollow |
| 2002-01-01 | 1 | 1 | follow |
| 2000-01-01 | 2 | 1 | follow |
| 2001-01-01 | 2 | 1 | unfollow |
| 2003-01-01 | 2 | 2 | follow |
| 2004-01-01 | 3 | 1 | follow |
| 2004-01-01 | 1 | 1 | upvote |
| 2004-01-01 | 2 | 1 | downvote |
+------------+---------+---------+----------+
此查询将返回:
+---------+
| USER_ID |
+---------+
| 1 |
| 3 |
+---------+
答案 3 :(得分:0)
我想我明白了:
SELECT * FROM (
SELECT * FROM users2posts
WHERE post_id=1
AND (action="follow" OR action="unfollow")
ORDER BY uts DESC
) AS temp
GROUP BY user_id;
然后我用PHP做循环:
foreach ($ROWS as $ROW)
if ($ROW['action'] == 'follow')
$FOLLOWERS[] = $ROW['user_id'];
将id直接从查询中删除仍然很好,但这应该可以。