実際の位置を維持しようとするのではなく、ユーザーがムービーを特定の位置に配置した位置とタイムスタンプの組み合わせを使用すると、データの選択と更新の両方を行うかなり単純な手段を実現できます。例えば; データの基本セット:
create table usermovies (userid int, movieid int, position int, positionsetdatetime datetime)
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (123, 99, 1, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (123, 98, 2, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (123, 97, 3, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (123, 96, 4, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (123, 95, 5, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (123, 94, 6, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (987, 99, 1, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (987, 98, 2, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (987, 97, 3, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (987, 96, 4, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (987, 95, 5, getutcdate())
insert into usermovies (userid, movieid, position, positionsetdatetime)
values (987, 94, 6, getutcdate())
次のようなクエリを使用してユーザーの映画をクエリするとします。
;with usermovieswithrank as (
select userid
, movieid
, dense_rank() over (partition by userid order by position asc, positionsetdatetime desc) as movierank
from usermovies
)
select * from usermovieswithrank where userid=123 order by userid, movierank asc
次に、期待される結果が得られます。
USERID MOVIEID MOVIERANK
123 99 1
123 98 2
123 97 3
123 96 4
123 95 5
123 94 6
映画のランキングの 1 つを移動するには、position 列と positionsetdatetime 列を更新する必要があります。たとえば、userid 123 が映画 95 をランク 5 からランク 2 に移動する場合、次のようにします。
update usermovies set position=2, positionsetdatetime=getutcdate()
where userid=123 and movieid=95
結果は次のようになります (更新後に上記の SELECT クエリを使用):
USERID MOVIEID MOVIERANK
123 99 1
123 95 2
123 98 3
123 97 4
123 96 5
123 94 6
次に、userid 123 が映画 96 をランク 1 に移動した場合:
update usermovies set position=1, positionsetdatetime=getutcdate()
where userid=123 and movieid=96
我々が得る:
USERID MOVIEID MOVIERANK
123 96 1
123 99 2
123 95 3
123 98 4
123 97 5
123 94 6
もちろん、usermovies テーブル内で position 列の値が重複することになりますが、この方法ではその列を表示することはありません。positionsetdatetime と一緒に使用して、各ユーザーの並べ替えられたランクを決定し、決定したランクは次のとおりです。本当の位置。
ある時点で、positionsetdatetime を参照せずに位置列に映画のランキングを適切に反映させたい場合は、上記の選択クエリの movierank を使用して、決定された映画のランキングに実際には影響しないため、usermovies の位置列の値を更新できます。