2017-02-13 10 views
0

Я адаптирую этот simpler working example в несколько более сложный прецедент. Вместо того, чтобы присоединяться к одному внешнему ключу, я провожу тест IF по успешному сопоставлению двух внешних ключей, и я добавил в предложение WHERE в подзапросе, чтобы отфильтровать определенные строки для того, чтобы иметь право на ранжирование. Однако теперь значение ранга никогда не увеличивается (поэтому тест IF всегда терпит неудачу). Виновником является подзапрос ИНЕКЕ:Выберите верхние N элементов на группу с условиями в подзапросе

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 работать, не мешая ранжированию?

Here is the schema (включая данные испытаний) для всех, с кем можно играть, чтобы получить эту работу.

+0

'WHERE cand.is_pseudocandidate! = 1' преобразует' LEFT JOIN кандидатов cand' в INNER JOIN. Но я не знаю, если это имеет значение. –

ответ

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; 
+0

К сожалению, я получаю те же результаты с этим решением. Рейтинги по-прежнему не увеличиваются. –

+0

У вас есть создание таблиц и даты выборки. вы можете поместить его на http://sqlfiddle.com/ –

+1

Возможно, вам следует начать с этого. – Strawberry