SQL RANK () над PARTITION для объединенных таблиц

У меня есть две таблицы RSLTS и CONTACTS:

RSLTS

 QRY_ID  |  RES_ID  |  SCORE
-----------------------------
   A     |    1     |    15
   A     |    2     |    32
   A     |    3     |    29
   C     |    7     |    61
   C     |    9     |    30

КОНТАКТЫ

 C_ID  |  QRY_ID  |  RES_ID
----------------------------
  1    |    A     |    2
  2    |    A     |    1
  3    |    C     |    9

Я пытаюсь создать отчет, который бы отображал для каждой записи CONTACT (C_ID) RANK() из RES_ID (по SCORE) в таблице RSLTS в своей группе ( QRY_ID). Используя приведенные выше данные, это будет выглядеть так:

 C_ID  |  QRY_ID  |  RES_ID  |  SCORE  |  Rank
-----------------------------------------------
  1    |    A     |    2     |    32   |   1
  2    |    A     |    1     |    15   |   3
  3    |    C     |    9     |    30   |   2

До сих пор я пробовал это, но он возвращает Rank = 1 для последней строки (и rank = 2 для второй, что также неверно)

SELECT
    C.*
    ,R.SCORE
    ,RANK() OVER (PARTITION BY R.QRY_ID ORDER BY R.SCORE DESC)
FROM CONTACTS C LEFT JOIN RSLTS R
ON C.RES_ID = R.RES_ID
AND C.QRY_ID = R.QRY_ID

ОБНОВЛЕНИЕ: SQLFiddle


person greener    schedule 19.12.2012    source источник
comment
Вы уверены? Я получаю ваши ожидаемые результаты. Кроме того, что случилось со всеми сокращениями? И действительно ли вы имеете в виду DENSE_RANK() (который закроет «пробелы» между рейтингами)?   -  person Clockwork-Muse    schedule 20.12.2012
comment
Спасибо за SQLFiddle. Данные, которые у меня есть, показывают нечто иное. Я обновил данные в этом SQLFiddle (sqlfiddle.com/#!3/6ef2f/1), где в последней записи должно быть указано ранг = 2 вместо 1, так как 61 ›30   -  person greener    schedule 20.12.2012
comment
На данный момент ваши результаты эквивалентны _1 _.... Вы уверены, что вам нужно разделить (у вас нет повторов в вашем рейтинге).   -  person Clockwork-Muse    schedule 20.12.2012


Ответы (2)


Так как ранг совершенно не зависит от контактов

RANKED_RSLTS

 QRY_ID  |  RES_ID  |  SCORE |  RANK
-------------------------------------
   A     |    1     |    15  |   3
   A     |    2     |    32  |   1
   A     |    3     |    29  |   2
   C     |    7     |    61  |   1
   C     |    9     |    30  |   2

Таким образом :

SELECT
    C.*
    ,R.SCORE
    ,MYRANK
FROM CONTACTS C LEFT JOIN
(SELECT  *,
 MYRANK = RANK() OVER (PARTITION BY QRY_ID ORDER BY SCORE DESC)
  FROM RSLTS)  R
ON C.RES_ID = R.RES_ID
AND C.QRY_ID = R.QRY_ID
person Johan Buret    schedule 20.12.2012

person    schedule
comment
Пожалуйста, не предоставляйте ответы только в виде кода, а объясните, почему / как работает решение. Также отредактируйте свой код, чтобы он отображался правильно. - person jotasi; 16.08.2016
comment
Конечно, сделаю в следующий раз. Просто новичок и постараюсь ответить на вопрос. Спасибо за совет. - person sai wang; 16.08.2016
comment
Вы по-прежнему можете редактировать свой пост и добавлять пояснения! - person jotasi; 16.08.2016