问题
What I am trying to do is equivalent to a "music charts" table.
I have a table of video plays, and i want to rank the videos that have been played in the last 24 hours, and compare them to the rank they were the 24 hours before that.
So the output should be the VideoID, The current Rank of the ID, and the rank the day previous of the ID
The table consists of:
PlayID (the specific id to the play table)
IP (IP address of the user who played the video)
VIDEOID (ID of the specific video, what needs to be ranked by most occurances)
playtime (linux time when played)
the table is called video_plays7d.
This has been stumping me, and i cannot figure it out, any ideas?
回答1:
You'll first need a full list of ALL videos so if any played on one day and not the other, you won't loose that instance... The inner pre-query should get ALL possible video's and their respective counts on current date or before, but the WHERE clause restricts down to just the two days. Inner query also pre-orders ITs FIRST pass by the "Day Before" count descending and applies @var to build out the rank. From THAT, requery all those results, but this time, sort by the "TODAY" count descending and apply rank to THAT set. When all is finished, it should show the ranks as of today from 1-?, but the day before ranking may be staggered respectively to their count.
select
AllPlays.VideoID,
AllPlays.CntToday,
@RankToday := @RankToday +1 as TodayRank,
AllPlays.CntBefore,
AllPlays.BeforeRank
from
( select vp.VideoID,
sum(if(date(FROM_UNIXTIME(vp.playtime )) = curdate(), 1, 0 )) as CntToday,
sum(if(date(FROM_UNIXTIME(vp.playtime )) < curdate(), 1, 0 )) as CntBefore,
@RankBefore := @RankBefore +1 as BeforeRank
from
video_plays7d vp
join ( select @RankBefore := 0 ) SQLVars
where
date( FROM_UNIXTIME(vp.playtime ) ) >= date_sub( curdate(), interval 1 day )
group by
vp.VideoID
order by
CntBefore DESC
) As AllPlays
join ( select @RankToday := 0 ) as SqlVars2
order by
AllPlays.CntToday DESC
来源:https://stackoverflow.com/questions/9131420/mysql-rank-comparison