2012-12-19 12 views
8

Ho due tavoli RSLTS e contatti:SQL RANK() su PARTITION su tabelle unite

RSLTS

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

CONTATTI

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

Sto cercando di creare un report che dovrebbe mostrare, per ogni record CONTACT (C_ID), RANK() di RES_ID (da SCORE) nella tabella RSLTS all'interno del relativo gruppo (QRY_ID). Utilizzando i dati di cui sopra, sarebbe simile a questa:

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

Finora, ho provato questo ma restituisce Classifica = 1 per l'ultima riga (e rango = 2 per il secondo, che è anche sbagliato)

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

Sei sicuro? [Ottengo i risultati attesi] (http://sqlfiddle.com/#!3/da810/1). Inoltre, che succede con tutte le abbreviazioni? E potresti davvero voler dire 'DENSE_RANK()' (che chiuderà 'spazi vuoti' tra le classifiche)? –

+0

Grazie per SQLFiddle. I dati che ho qui localmente hanno mostrato qualcosa di diverso. Ho aggiornato i dati in questo SQLFiddle (http://sqlfiddle.com/#!3/6ef2f/1) dove l'ultimo record dovrebbe mostrare rank = 2 invece di 1 dal 61> 30 – greener

+0

Al momento i tuoi risultati sono equivalenti a ' RANK() OVER (ORDER BY r.score DESC) '.... Sei sicuro di aver bisogno di partizionare (non hai alcuna ripetizione nella tua classifica). –

risposta

11

Come il rango non dipende affatto dai contatti

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 

Così:

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

Questo ha funzionato. Molte grazie. – 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

Si prega di non fornire un codice solo risposte, ma spiegare perché/come funziona la soluzione. Inoltre, si prega di modificare il codice per mostrare correttamente. – jotasi

+0

Certo, farà la prossima volta. Basta un novellino e prova a rispondere alla domanda. Grazie per il vostro consiglio. –

+0

Puoi ancora modificare il tuo post e aggiungere una spiegazione! – jotasi

Problemi correlati