使用子查询中的条件为每个组选择前N个项目

时间:2017-02-13 20:25:01

标签: mysql subquery

我正在将此 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(包括测试数据)供所有人使用以实现此功能。

1 个答案:

答案 0 :(得分:0)

你没有初始化排名只在左边JOIN 面对面之间放置一条线我认为那就是

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;