我有以下数据:
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)相互抵消。
答案 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表示事情发生的顺序。