Nếu bạn sử dụng kết hợp vị trí và dấu thời gian mà người dùng đặt phim ở vị trí nhất định thay vì cố gắng duy trì vị trí thực, thì bạn có thể đạt được một phương tiện khá đơn giản gồm cả CHỌN và CẬP NHẬT dữ liệu. Ví dụ; một bộ cơ sở dữ liệu:
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())
Nếu bạn truy vấn phim của người dùng sử dụng một truy vấn như thế này:
;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
Sau đó, bạn sẽ nhận được kết quả mong đợi:
USERID MOVIEID MOVIERANK
123 99 1
123 98 2
123 97 3
123 96 4
123 95 5
123 94 6
Để di chuyển một trong những thứ hạng của phim chúng ta cần cập nhật vị trí và cột positionsetdatetime. Ví dụ, nếu userid 123 di chuyển phim 95 từ vị trí thứ 5 để xếp hạng 2 thì chúng ta làm điều này:
update usermovies set position=2, positionsetdatetime=getutcdate()
where userid=123 and movieid=95
Những kết quả trong việc này (bằng cách sử dụng truy vấn SELECT ở trên sau khi cập nhật):
USERID MOVIEID MOVIERANK
123 99 1
123 95 2
123 98 3
123 97 4
123 96 5
123 94 6
Sau đó, nếu userid 123 di chuyển phim 96 để xếp hạng 1:
update usermovies set position=1, positionsetdatetime=getutcdate()
where userid=123 and movieid=96
Chúng tôi nhận được:
USERID MOVIEID MOVIERANK
123 96 1
123 99 2
123 95 3
123 98 4
123 97 5
123 94 6
Tất nhiên bạn sẽ kết thúc với các giá trị cột vị trí trùng lặp trong bảng usermovies, nhưng với phương pháp này bạn sẽ không bao giờ hiển thị cột đó, bạn chỉ cần sử dụng nó cùng với positionsetdatetime để xác định thứ hạng được sắp xếp cho từng người dùng và thứ hạng bạn xác định là vị trí thực sự.
Nếu tại một thời điểm nào đó bạn muốn cột vị trí phản ánh đúng thứ hạng phim mà không tham chiếu đến vị tríđịnh giờ bạn có thể sử dụng movierank từ truy vấn chọn ở trên để cập nhật giá trị cột vị trí usermovies, vì nó sẽ không thực sự ảnh hưởng đến xếp hạng phim được xác định.
và truy vấn SQL sẽ liệt kê phim là gì? – bjan
@bjan Lựa chọn nên khá đơn giản ... cập nhật là một mẹo nhỏ hơn, nhưng tôi nghĩ rằng nó hoạt động. – McGarnagle
Theo thử nghiệm của tôi, kết quả là trùng lặp trước đó !! – bjan