我正在从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
我想通过updated_at字段选择按id_partner顺序排名的行。当id_partner与RANK应该增加1之前的行相同时。当它与之前不同时,它应该重置为1.
但我的查询根本不起作用。我仍然在所有行上排名第一。你能帮我找错吗?
谢谢你的帮助!
答案 0 :(得分:2)
在MySQL / MariaDB中使用变量很棘手。变量只能在一个语句中使用和分配(正如您所做的那样)。但是,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;
更简单。但是,这似乎是您的目标代码:
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中),除非使用子查询,否则有时变量不能正常工作。所以,试试这个:
{{1}}