如果您使用用户将电影放置在给定位置的位置和时间戳的组合,而不是尝试保持实际位置,那么您可以实现一种相当简单的方法来选择和更新数据。例如; 一组基本数据:
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
要移动电影的排名之一,我们需要更新 position 和 positionsetdatetime 列。例如,如果用户 ID 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
然后如果用户 ID 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 表中得到重复的位置列值,但是使用这种方法,您将永远不会显示该列,您只需将其与 positionsetdatetime 一起使用来确定每个用户的排序排名,您确定的排名是真实的位置。
如果您希望位置列在不参考 positionsetdatetime 的情况下正确反映电影排名,您可以使用上面选择查询中的 movierank 来更新 usermovies 位置列值,因为它实际上不会影响确定的电影排名。