我有许多行的MySQL表。该表具有知名度列。如果我按热门程度排序,我可以得到每个项目的排名。是否有可能检索特定项目的等级不排序整个表?我不认为如此。这是否正确?

另一种方法是,为通过所有的行存储等级,排序整个表,然后循环创建新列和更新排名。这是非常低效的。有可能的方式在单个查询做到这一点?

有帮助吗?

解决方案

有没有办法计算的东西的顺序(你叫什么等级),而第一排序表或存储级别。

如果您的表也被恰当不过索引(上人气指数),它是平凡的数据库排序这个,所以你可以得到你的排名。我建议像下面这样:

全选,包括秩

SET @rank := 0;
SELECT t.*, @rank := @rank + 1
FROM table t
ORDER BY t.popularity;

要取与特定的“ID”的项目然后可以简单地使用一个子查询,如下所示:

选择一个,包括秩

SET @rank := 0;
SELECT * FROM (
  SELECT t.*, @rank := @rank + 1
  FROM table t
  ORDER BY t.popularity
) t2
WHERE t2.id = 1;

其他提示

您是正确的,第二种方法是inefficent,如果排名列在每个表读取更新。然而,取决于有多少更新有数据库,你可以计算出每个更新的等级,并存储 - 它是缓存的一种形式。然后,您正在转向一个计算的字段为固定值字段。

该影片盖在MySQL缓存,虽然它是特定轨道和是一个稍微不同形式的缓存,被一个非常类似的缓存策略。

如果您使用的是InnoDB表,那么你可以考虑在普及列建立一个聚集索引。 (仅当上流行的顺序是一种常见的查询)。该决定还取决于普及柱如何变化是(0 - 3不是那么好)。

您可以看一下对聚集索引这个信息,看看是否适合您的情况:的 http://msdn.microsoft.com/en-us/library/ms190639.aspx

这是指SQL服务器,但概念是在这一样,也期待了MySQL文档。

如果你这样做是使用PDO,那么你需要修改查询到所有是一个语句中,为了得到它的正常工作。请参见 PHP / PDO / MySQL的:转换多个查询到单查询

所以hobodave的答案就是这样的:

SELECT t.*, (@count := @count + 1) as rank
FROM table t 
CROSS JOIN (SELECT @count := 0) CONST
ORDER BY t.popularity;

hobodave的解决方案是非常好的。或者,你可以添加一个单独的排名列,然后,每当行的普及UPDATEd,查询,以确定人气更新是否其相对排名变化到行上面和下面,然后UPDATE影响了3行。你必须配置文件,看看其方法是更有效的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top