在类似博客的网站中,所有用户都可以“加注”新闻(=将其加入书签,将其标记为“收藏”)。 我有一个统计数据的mysql表。
table_news_stats
id_news
total_stars (int) //Total number of users who starred this news
placement (int)
placement
字段非常直观:如果您按total_stars
字段订购所有新闻,则会收到每条新闻placement
。因此,大多数明星的新闻都是数字1
,依此类推。
所以,假设我的table_news_stats
中有700条记录,而且每个记录都有id
和total_stars
,我怎样才能更新placement
字段每个记录自动?哪个查询更快/更好?
table_news_stats内容示例:
First record (A):
1-3654-?
Second record (B):
2-2456-?
Third record (C):
3-8654-?
如果按星号计算记录: 记录的顺序是C - A - B
所以...结果将是:
First record (A):
1-3654-2
Second record (B):
2-2456-3
Third record (C):
3-8654-1
澄清:
为什么我需要placement
字段呢?
这很简单......每个月的第一天,放置字段将由cronjob填充。基本上它将提供每个新闻在受欢迎程度方面的排名“快照”(就像当月初)。因此,感谢展示位置字段,我将获得以下信息:
"The 1st day of this month the 'top starred' news list was like this:
1- News C
2- NewsA
3- News B "
然后,通过查询“SELECT * FROM table_news_stats ORDER BY total_stars DESC”,我可以获得新的排名(实时)。
因此,我将获得以下信息:
"At the time the page is loaded, the 'top starred' news list is like this:
1- News A
2- News C
3- News B "
最后,通过比较两个排名,我获得了最后一条信息:
"News A has gained a position" +1
"News C has lost a position" -1
"News B has no change in position" +0
如果有更好的方法,请告诉我。
答案 0 :(得分:5)
我猜你不需要update
表格:
SELECT *
FROM table_news_stats
ORDER BY total_stars DESC
但如果你想知道每个人的位置,你可以:
SELECT *, IF(@idx IS NULL,@idx:= 1,@idx:= @idx+1)
FROM table_news_stats
ORDER BY total_stars DESC
如果你还需要update
之类的东西:
UPDATE table_news_stats
SET placement = FIND_IN_SET(id_news,(SELECT GROUP_CONCAT(t.id_news) FROM (SELECT id_news
FROM table_news_stats
ORDER BY total_stars DESC) t ))
答案 1 :(得分:3)
考虑以下
mysql> select * from test ;
+------+-------------+-----------+
| id | total_stars | placement |
+------+-------------+-----------+
| 1 | 3 | 0 |
| 2 | 6 | 0 |
| 3 | 7 | 0 |
| 4 | 2 | 0 |
| 5 | 9 | 0 |
| 6 | 2 | 0 |
| 7 | 1 | 0 |
+------+-------------+-----------+
现在使用以下内容,您可以将placement
更新为
update test t1 join
(
select *,
@rn:= if(@prev = total_stars,@rn,@rn+1) as rank ,
@prev:= total_stars
from test,(select @rn:=0,@prev:=0)r
order by total_stars desc
)t2
on t2.id = t1.id
set t1.placement = t2.rank ;
mysql> select * from test order by placement ;
+------+-------------+-----------+
| id | total_stars | placement |
+------+-------------+-----------+
| 5 | 9 | 1 |
| 3 | 7 | 2 |
| 2 | 6 | 3 |
| 1 | 3 | 4 |
| 4 | 2 | 5 |
| 6 | 2 | 5 |
| 7 | 1 | 6 |
+------+-------------+-----------+
请注意,如果领带将具有相同的位置。