我在运行查询排名时遇到问题。 内部SELECT按排名顺序给出行,对于每一行,变量@rank增加,如果不是等于前一个等级的位置。 但@rank并不是真正的正确位置。
我正在尝试对具有最高价值的人进行分组和排序。
SET @prev := NULL;
SET @curr := NULL;
SET @rank := 0;
SELECT
@prev := @curr,
@curr := SUM( a.value ) AS SUM_VALUES,
@rank := IF(@prev = @curr, @rank, @rank+1) AS rank,
b.id AS b_id,
b.name AS b_nome
FROM
a INNER JOIN b ON ( a.b_id = b.id )
GROUP BY b.id
ORDER BY SUM_VALUES DESC;
结果:
----------------------------------------------------
@prev := @curr | SUM_VALUES | rank | b_id | b_nome
---------------|------------|------|-------|--------
NULL | 10 | 2 | 2 | BBB
NULL | 2 | 1 | 1 | AAA
BBB在排名中排名第一,AAA排名第二。 但是这不会发生,一个关于发生了什么的想法?
测试转储
CREATE TABLE `a` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`b_id` INT(10) NULL DEFAULT NULL,
`value` INT(10) NULL DEFAULT NULL,
`name` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `b_id` (`b_id`),
CONSTRAINT `fk_b` FOREIGN KEY (`b_id`) REFERENCES `b` (`id`)
)
ENGINE=InnoDB;
CREATE TABLE `b` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB;
INSERT INTO `b` (`id`, `name`) VALUES (1, 'AAA');
INSERT INTO `b` (`id`, `name`) VALUES (2, 'BBB');
INSERT INTO `a` (`id`, `b_id`, `value`, `name`) VALUES (1, 1, 2, 'smaller');
INSERT INTO `a` (`id`, `b_id`, `value`, `name`) VALUES (2, 2, 10, 'bigger');
答案 0 :(得分:3)
<强>具有强>
它会很慢,但是having
子句将在之后运行所有选择,连接,where和group by已完成并完全解析。
唯一的问题是having
不使用索引,而where
确实使用索引。
SELECT
ranking stuff
FROM
lot of tables
WHERE simple_condition
HAVING filters_that_run_last
明确联接
请注意,您不必混合使用显式和隐式连接
如果您想要交叉加入,则可以使用cross join
关键字。
....
) AS Ranking
CROSS JOIN (SELECT @curr := null, @prev := null, @rank := 0) InitVars
WHERE
Ranking.regional_id = 1003
答案 1 :(得分:2)
首先,谢谢大家!
我找到了一种方法来返回预期的结果,使其他选择2
A)首先选择分组和排序
SELECT
SUM( a.value ) AS SUM_VALUES,
b.id AS b_id,
b.name AS b_name
FROM
a INNER JOIN b ON ( a.b_id = b.id )
GROUP BY b.id
ORDER BY SUM_VALUES DESC
B)我做这个排名列表
SELECT
R.*,
@prev := @curr,
@curr := R.SUM_VALUES,
@rank := IF(@prev = @curr, @rank, @rank+1) AS rank
FROM (
SELECT
SUM( a.value ) AS SUM_VALUES,
b.id AS b_id,
b.name AS b_name
FROM
a INNER JOIN b ON ( a.b_id = b.id )
GROUP BY b.id
ORDER BY SUM_VALUES DESC
) AS R
C)最后,只需选择重要的内容
SELECT
Ranking.b_id,
Ranking.b_name,
Ranking.rank
FROM
(
SELECT
R.*,
@prev := @curr,
@curr := R.SUM_VALUES,
@rank := IF(@prev = @curr, @rank, @rank+1) AS rank
FROM (
SELECT
SUM( a.value ) AS SUM_VALUES,
b.id AS b_id,
b.name AS b_name
FROM
a INNER JOIN b ON ( a.b_id = b.id )
GROUP BY b.id
ORDER BY SUM_VALUES DESC
) AS R
) AS Ranking
WHERE
Ranking.b_id = 1
此查询的结果是:
+------+--------+------+
| b_id | b_name | rank |
+------+--------+------+
| 1 | AAA | 2 |
+------+--------+------+