【问题标题】:Calculating a row position in the table计算表格中的行位置
【发布时间】:2009-08-18 16:40:29
【问题描述】:

假设我有一个这样的表(这只是一个简化的例子,我说的实际表要复杂得多):

CREATE TABLE media (
id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
voted INT NOT NULL DEFAULT 0,
rating FLOAT NOT NULL DEFAULT 0
) ENGINE = INNODB;

voted 列代表项目获得的投票数,rating 列代表项目的总评分。

现在,我想做的是根据 id 从表中选择一个项目,例如:

SELECT m.* FROM media AS m WHERE id = 5;

但是,此外,我想根据 rating 列计算这一行的位置,并将其作为附加列获取,假设称为 site_rank(因此row 是它的 site_rank 越高,我希望我解释得很好)。我的猜测是这可以通过子选择查询来实现,但我不知道该怎么做。

有什么帮助吗?

【问题讨论】:

  • 我可以建议实施一个每隔一段时间更新一次的 Site_Rank 列吗?可能会容易得多。
  • 这样你就可以进行一个非常大的数据库调用(或几个较小的),然后更新每一个。然后在 5 分钟内你不需要做任何其他事情。

标签: php sql mysql


【解决方案1】:
SELECT count(*) FROM media WHERE rating > (SELECT rating FROM media WHERE id = 5);

【讨论】:

    【解决方案2】:

    这将为大多数投票媒体输出高rank

    如果您希望投票最多的人排名较低(例如,投票最多的人将获得1rank),只需反转子查询中的符号即可。

    SELECT  mo.*,
            (
            SELECT  COUNT(*)
            FROM    media mi
            WHERE   (mi.rating, mi.id) <= (mo.rating, mo.id)
            ) AS rank
    FROM    media mo
    WHERE   mo.id = 5
    

    【讨论】:

      【解决方案3】:
      SELECT
          m1.*,
          (SELECT COUNT(*) FROM media AS m2 WHERE m2.rating > m1.rating) AS site_rank
      FROM
          media AS m1
      WHERE
          id = 5;
      

      请注意,这并不能定义完整的排序,因为可能存在具有相同评级的项目,它们将报告相同的网站排名。

      【讨论】:

        【解决方案4】:

        MySQL 是否支持标准的 SQL rank() 函数?它完全符合您的要求。

        select
          *,
          rank() over (
            order by rating desc
          ) as site_rank
        from media
        

        【讨论】:

          猜你喜欢
          • 2013-06-04
          • 2017-07-01
          • 2016-10-13
          • 1970-01-01
          • 1970-01-01
          • 2013-02-20
          • 2014-12-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多