0

私は次のデータを持っています:

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の場合、投票はキャンセルされます。3行目で、ユーザーは再び行動し、そのステータスはアクティブです。後でキャンセルする行がない場合にのみ、行を選択できるようにする必要があります

ユーザーごとに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 

(1-2)と(4-5)が互いに打ち消し合うため、ここでは3行目だけが必要になります。

4

2 に答える 2

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

しかし、速度の向上(もしあれば!)が明確さの欠如を補うことができるかどうかはわかりません。

于 2012-09-25T21:05:42.833 に答える
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はテーブルの名前です。中央のselectは、指定されたvote_idの最後にキャンセルされた行を検索します。外側の部分は、キャンセルする行の前にあるすべての行を除外します。これは、IDが発生した順序を示していることを前提としています。

于 2012-09-25T21:10:15.690 に答える