2012-12-19 14 views
8

Mam dwie tabele RSLTS i kontakty:SQL RANK() na partycji, na połączonych tabelach

RSLTS

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

KONTAKT

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

Próbuję utworzyć raport, który pokaże dla każdego rekordu KONTAKT (C_ID), RANK() (przez SCORE) w tabeli w swojej grupie (QRY_ID). Wykorzystując dane powyżej, to będzie wyglądać następująco:

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

Dotychczas próbowałem tego, ale zwraca Rank = 1 dla ostatniego rzędu (i rangi = 2 dla drugiego, który jest również źle)

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 

UPDATE: SQLFiddle

+2

Czy jesteś pewien? [Otrzymuję oczekiwane wyniki] (http://sqlfiddle.com/#!3/da810/1). Co się dzieje z wszystkimi skrótami? I czy naprawdę masz na myśli 'DENSE_RANK()' (co spowoduje zamknięcie "luk" między rankingami)? –

+0

Dzięki za pytanie SQLFiddle. Dane, które mam tutaj na miejscu, pokazują coś innego. Zaktualizowałem dane w tym języku SQLFiddle (http://sqlfiddle.com/#!3/6ef2f/1), gdzie ostatni rekord powinien pokazywać rank = 2 zamiast 1, ponieważ 61> 30 – greener

+0

W chwili, gdy twoje wyniki są równoważne z ' RANK() OVER (ORDER BY r.score DESC) '.... Czy na pewno chcesz podzielić (nie ma żadnych powtórzeń w rankingu). –

Odpowiedz

11

Ponieważ pozycja nie zależy w ogóle od kontaktów

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 

Zatem:

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

To działało. Wielkie dzięki. – greener

0
SELECT a.C_ID,a.QRY_ID,a.RES_ID,b.SCORE,ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS [RANK] 
FROM CONTACTS a JOIN RSLTS b ON a.QRY_ID=b.QRY_ID AND a.RES_ID=b.RES_ID 
ORDER BY a.C_ID 
+0

Proszę nie udzielać odpowiedzi tylko do kodu, ale wyjaśnić, dlaczego/jak działa to rozwiązanie. Zmodyfikuj również swój kod, aby wyświetlał się poprawnie. – jotasi

+0

Oczywiście, zrobię to następnym razem. Tylko nowicjusz i spróbuj odpowiedzieć na pytanie. Dzięki za radę. –

+0

Nadal możesz edytować swój post i dodać wyjaśnienie! – jotasi

Powiązane problemy