mysql只选择未取消的行

时间:2012-09-25 20:52:04

标签: mysql select

我有以下数据:

id  vote_id  user_id  status 
1   1        1        1         the vote is active 
2   1        1        2         vote is canceled 
3   1        1        1         vote is active again 

状态始终为1,如果状态为2,则取消投票。在第三行,用户再次操作并且其状态为活动状态。我只需要在之后没有取消行的情况下选择一行

考虑到我不仅要为每个用户1个vote_id执行此操作,如何为所有仍处于活动状态的用户获取所有行!?

完整的数据样本如下所示:

id  vote_id  user_id  status 
1   1        1        1         - vote1 is active 
2   1        1        2         - vote1 is canceled 
3   1        1        1         - vote1 is active again 
4   2        1        1         - vote2 is active 
5   2        1        2         - vote2 is canceled 

我在这里只需要第3行,因为(1-2)和(4-5)相互抵消。

2 个答案:

答案 0 :(得分:1)

鉴于情况

id, vote_id, user_id, status 
1,1,1,1 - the vote is active 
2,1,1,2 - vote is canceled 
3,1,1,1 - vote is active again 

我认为系统不允许取消投票,除非该投票处于活动状态,除非处于取消状态,否则不会重新激活。

因此,如果投票的“州1”的数量等于“州2”的数量,则取消投票;否则它是活跃的。

根据这一假设,

SELECT id, vote_id, user_id, active AS status FROM
    ( SELECT MAX(id) AS id,
           SUM(CASE WHEN status = 1 THEN 1 WHEN status = 2 THEN -1 ELSE 0 END)
              AS active,
           user_id,
           vote_id
    FROM votes GROUP BY user_id, vote_id ) AS votes
WHERE votes.status = 1;

或者 - 我不喜欢这个,因为status名称含糊不清 -

SELECT MAX(id) AS id,
    SUM(CASE WHEN status = 1 THEN 1 WHEN status = 2 THEN -1 ELSE 0 END) AS status,
    user_id,
    vote_id
FROM votes GROUP BY user_id, vote_id
HAVING status = 1;

如果您确定状态值,并且没有其他人,您也可以尝试

SUM((1-status)*2+1) AS status

但我不知道速度增益(如果有的话)是否可以弥补缺乏清晰度。

答案 1 :(得分:0)

我想出了这个

select t.*
from @temp t
left join (select max(id) as lastCanceledId, vote_id
            from @temp
            where status = 2
            group by vote_id) cancels on t.vote_id = cancels.vote_id
where COALESCE(cancels.lastCanceledId, 0) < t.id
and t.Status = 1

其中@temp是表的名称。中间的选择查找给定的vote_id的最后一个取消的行。外部部分过滤掉取消行之前的所有行。这假设id表示事情发生的顺序。