mysql - MariaDB/MySQL RANK() 实现

标签 mysql sql mariadb rank

我正在从 MS SQL Server 迁移到 MariaDB 10.0。我有使用 RANK() PARTITION BY 的查询。我已经在我的表上创建了某种 RANK() 实现,但它无法正常工作。

原始查询是:

RANK() OVER (PARTITION BY visits.id_partner ORDER BY visits.updated_at DESC) AS rank

我对 MariaDB/MySQL 的实现:

SELECT
    ...,
    (
        CASE visits.id_partner
            WHEN @currId THEN
                @curRow := @curRow + 1
            ELSE
                @curRow := 1 AND @currId := visits.id_partner
        END
    ) AS rank
FROM
    records rec
    JOIN visits ON visits.id = rec.id_visit,
    (
        SELECT
        @curRank := 0,
        @currId := NULL
    ) r
WHERE
    ...
ORDER BY visits.id_partner ASC, visits.updated_at DESC

我想选择按 id_partner order by updated_at 字段排名的行。当 id_partner 与前一行相同时,RANK 应加 1。当与之前不同时,应重置为 1。

但是我的查询根本不起作用。我仍然在所有行中排名第一。你能帮我找错吗?

谢谢你的帮助!

最佳答案

在 MySQL/MariaDB 中使用变量是很棘手的。一个变量只能在一个语句中使用和赋值(正如你所做的那样)。但是,AND 可以短路变量赋值。

我对 ROW_NUMBER() 使用了这样的结构。 RANK() 其实有点痛苦。 . . DENSE_RANK()ROW_NUMBER() 更简单。但是,这似乎是您的目标代码:

SELECT ...,
       (@rn := if(@currId = visits.id_partner, @rn + 1,
                  if(@currId := visits.id_partner, 1, 1)
                 )
       ) as rank
FROM records rec JOIN
     visits
     ON visits.id = rec.id_visit CROSS JOIN
     (SELECT @rn := 0, @currId := NULL) params
WHERE
    ...
ORDER BY visits.id_partner ASC, visits.updated_at DESC;

编辑:

在 MySQL 中(大概在 MariaDB 中),有时变量不能正常工作,除非你使用子查询。所以,试试这个:

SELECT . . .,
       (@rn := if(@currId = visits.id_partner, @rn + 1,
                  if(@currId := visits.id_partner, 1, 1)
                 )
       ) as rank
FROM (SELECT ...
      FROM records rec JOIN
           visits
           ON visits.id = rec.id_visit 
      WHERE
          ...
      ORDER BY visits.id_partner ASC, visits.updated_at DESC
     ) t CROSS JOIN
     (SELECT @rn := 0, @currId := NULL) params;

关于mysql - MariaDB/MySQL RANK() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33435162/

相关文章:

MySQL sum 默认返回0

MySQL 更新匹配某个值的行之后的所有行的值

php - 从php更新mysql数据库中的多条记录

MYSQL 子请求太长

php - 如何在 PHP 中按日期(今天、昨天、8 月 29 日、28 日等)对 SQL 中的 foreach 项目进行排序?

mysql - 如何在 MySQL 中启用 ONLY_FULL_GROUP_BY

mysql - 如何正确地将 mariadb 数据库从容器移动到主机

java - JDBC 字符编码

php - 根据另一个数组从数组中删除行

c# - 如何在 HQL 中使用 DATEPART 从 DATETIME 获取 YEAR