我正在改编此 simpler working example 到一个稍微复杂的用例。我没有加入一个外键,而是对两个外键的成功匹配进行 IF 测试,并且在子查询中添加了 WHERE 子句,以过滤掉某些符合排名资格的行。然而,现在排名值似乎永远不会增加(因此 IF 测试总是失败)。罪魁祸首是子查询 WHERE 子句:
WHERE cand.is_pseudocandidate != 1
在下面这个查询的子查询中:
SELECT contest_id, division_id, candidate_id, n_votes, rank, n_seats
FROM
( SELECT ccd.id, contest_id, ccd.division_id, ccd.candidate_id, n_votes, cont.n_seats,
@rank := IF(@current_contest = ccd.contest_id AND @current_div = ccd.division_id, @rank + 1, 1) AS rank,
@current_contest := ccd.contest_id,
@current_div := ccd.division_id
FROM candidates_contests_divisions ccd
LEFT JOIN candidates cand ON ccd.candidate_id = cand.id
LEFT JOIN contests cont ON ccd.contest_id = cont.id
WHERE cand.is_pseudocandidate != 1
ORDER BY ccd.contest_id, ccd.division_id, n_votes DESC
) ranked
WHERE rank <= 3;
当我注释掉该子查询 WHERE 子句时,查询按预期工作,但当然,它包含我不想要的行。
如何让这个子查询 WHERE 子句在不影响排名的情况下工作?
Here is the schema (包括测试数据)供任何人使用以使其正常工作。
最佳答案
你没有初始化排名只在left JOIN和WhERE之间放置一条线,我认为这就是全部
SELECT contest_id, division_id, candidate_id, n_votes, rank, n_seats
FROM
( SELECT ccd.id, contest_id, ccd.division_id, ccd.candidate_id, n_votes, cont.n_seats,
@rank := IF(@current_contest = ccd.contest_id AND @current_div = ccd.division_id, @rank + 1, 1) AS rank,
@current_contest := ccd.contest_id,
@current_div := ccd.division_id
FROM candidates_contests_divisions ccd
LEFT JOIN candidates cand ON ccd.candidate_id = cand.id
LEFT JOIN contests cont ON ccd.contest_id = cont.id
CROSS JOIN ( SELECT
@rank := 0
, @current_contest := -1
, @current_div := -1 ) as init
WHERE cand.is_pseudocandidate != 1
ORDER BY ccd.contest_id, ccd.division_id, n_votes DESC
) ranked
WHERE rank <= 3;
关于mysql - 使用子查询中的条件选择每组前 N 个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42212891/