如何获取关注帖子的所有用户

时间:2012-02-19 16:46:56

标签: php mysql

我有一个表格,可以跟踪每个用户相对于每个帖子的活动:

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子句将选择缩减为每个用户执行的最后操作。但是,查询似乎是在订购之前进行分组。它应该发生什么?我该如何解决?

4 个答案:

答案 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直接从查询中删除仍然很好,但这应该可以。