2015-01-29 10 views
5

sto cercando di fare quanto segueAVG di 3 istruzioni SELECT con GROUP BY

Ho un QA tabella che contiene il seguente:

TICKET_ID SKILL_ID SCORE   USER 
############################################### 
1   10   15   USER1 
1   20   5   USER1 
1   30   95   USER1 
2   40   20   USER1 
2   50   40   USER1 
3   60   70   USER1 
3   70   15   USER1 

un tavolo COMPETENZE fatti di:

SKILL_ID SKILL_NAME AREA_ID 
    10  SKILL1  1 
    20  SKILL2  1 
    30  SKILL3  2 
    40  SKILL4  2 
    50  SKILL5  2 
    60  SKILL6  3 
    70  SKILL7  3 

e un tavolo BIGLIETTI fatti di:

TICKET_ID TICKET_NUMBER 
    1   AAA 
    2   BBB 
    3   CCC 

QA ha un FK a BIGLIETTI utilizzando TICKET_ID e anche un FK per abilità usando SKILL_ID

Quello che avrebbe bisogno di fare è:

per ogni biglietto sotto controllo tabella di QA che la somma del punteggio in ogni area fa non andare oltre 100 e se conta come 0, quindi fai l'AVG dei 3 risultati e raggruppa per ticket_number che è in un'altra tabella Quindi per ogni caso dovrei contare il punteggio per ogni area, se> 100 allora 0 altrimenti lasciare il valore originale quindi fare la media dei 3 valori e raggruppare per il numero di ticket

Non sicuro se questo è possibile

Così, forse, per calcolare il punteggio di area_1 faccio la seguente:

SELECT DECODE(100 - SUM(SCORE), 
100,100, 
95,95, 
90,90, 
85,85, 
80,80, 
75,75, 
70,70, 
65,65, 
60,60, 
55,55, 
50,50, 
45,45, 
40,40, 
35,35, 
30,30, 
25,25, 
20,20, 
15,15, 
10,10, 
5,5, 
0) SCORE_A1 FROM QA WHERE SKILL_ID IN(SELECT SKILL_ID FROM SKILLS WHERE AREA_ID = 1) AND TICKET_NUMBER = :P2_TICKET_NUMBER AND QA.USER = :P2_USER GROUP BY 1 

per calcolare il punteggio di area_2 stessa cosa, ma cambiando la condizione WHERE (DOVE AREA_ID = 2 questa volta):

SELECT DECODE(100 - SUM(SCORE), 
100,100, 
95,95, 
90,90, 
85,85, 
80,80, 
75,75, 
70,70, 
65,65, 
60,60, 
55,55, 
50,50, 
45,45, 
40,40, 
35,35, 
30,30, 
25,25, 
20,20, 
15,15, 
10,10, 
5,5, 
0) SCORE_A1 FROM QA WHERE SKILL_ID IN(SELECT SKILL_ID FROM SKILLS WHERE AREA_ID = 2) AND TICKET_NUMBER = :P2_TICKET_NUMBER AND QA.USER = :P2_USER GROUP BY 1 

e per calcolare il punteggio di area_3 stessa cosa, ma cambiando la condizione WHERE (DOVE AREA_ID = 3):

SELECT DECODE(100 - SUM(SCORE), 
100,100, 
95,95, 
90,90, 
85,85, 
80,80, 
75,75, 
70,70, 
65,65, 
60,60, 
55,55, 
50,50, 
45,45, 
40,40, 
35,35, 
30,30, 
25,25, 
20,20, 
15,15, 
10,10, 
5,5, 
0) SCORE_A1 FROM QA WHERE SKILL_ID IN(SELECT SKILL_ID FROM SKILLS WHERE AREA_ID = 3) AND TICKET_NUMBER = :P2_TICKET_NUMBER AND QA.USER = :P2_USER GROUP BY 1 

Ognuno di t i suoi blocchi dà 1 valore di uscita

Quello che sto cercando di realizzare è avere come output AVG dei 3 blocchi da ticket_number

ho cercato di riassumere i 3 blocchi tutti insieme, ma non mi consente :

SELECT DECODE(100 - SUM(SCORE), 
100,100, 
95,95, 
90,90, 
85,85, 
80,80, 
75,75, 
70,70, 
65,65, 
60,60, 
55,55, 
50,50, 
45,45, 
40,40, 
35,35, 
30,30, 
25,25, 
20,20, 
15,15, 
10,10, 
5,5, 
0) SCORE_A1 FROM QA WHERE SKILL_ID IN(SELECT SKILL_ID FROM SKILLS WHERE AREA_ID = 1) AND TICKET_NUMBER = :P2_TICKET_NUMBER AND QA.USER = :P2_USER GROUP BY 1 
+ 
SELECT DECODE(100 - SUM(SCORE), 
100,100, 
95,95, 
90,90, 
85,85, 
80,80, 
75,75, 
70,70, 
65,65, 
60,60, 
55,55, 
50,50, 
45,45, 
40,40, 
35,35, 
30,30, 
25,25, 
20,20, 
15,15, 
10,10, 
5,5, 
0) SCORE_A1 FROM QA WHERE SKILL_ID IN(SELECT SKILL_ID FROM SKILLS WHERE AREA_ID = 2) AND TICKET_NUMBER = :P2_TICKET_NUMBER AND QA.USER = :P2_USER GROUP BY 1 
+ 
SELECT DECODE(100 - SUM(SCORE), 
100,100, 
95,95, 
90,90, 
85,85, 
80,80, 
75,75, 
70,70, 
65,65, 
60,60, 
55,55, 
50,50, 
45,45, 
40,40, 
35,35, 
30,30, 
25,25, 
20,20, 
15,15, 
10,10, 
5,5, 
0) SCORE_A1 FROM QA WHERE SKILL_ID IN(SELECT SKILL_ID FROM SKILLS WHERE AREA_ID = 3) AND TICKET_NUMBER = :P2_TICKET_NUMBER AND QA.USER = :P2_USER GROUP BY 1 

Grazie

+0

si prega di notare che con la vostra espressione DECODE se il 100 - SUM (SCORE) non è divisibile per 5 ci sarà un ZERO come risultato. Cioè se 100 - SUM (SCORE) = 73 ci sarà 0. È questo che ti aspetti? – cha

+0

Puoi confermare che stai usando Oracle (funzione 'DECODE')? –

+0

Ciao, grazie per la risposta, sto usando oracle 12c quindi sì è la funzione di decodifica dell'oracolo. Come verrebbe controllato invece di utilizzare la funzione di decodifica? Ho visto che è possibile inserire un caso all'interno di una selezione, ma il problema principale è che non so come mettere tutto insieme al fine di avere la media delle 3 aree per ogni numero di biglietto. Grazie a – ChrisA

risposta

3

si prega di provare la seguente query:

SELECT 
    AREAS_SCORES.USER, 
    AREAS_SCORES.TICKET_ID, 
    AREAS_SCORES.TICKET_NUMBER, 
    AVG(CASE 
      WHEN AREAS_SCORES.AREA_SUM_SCORE > 100 THEN 0 
      ELSE AREAS_SCORES.AREA_SUM_SCORE 
     END) AVG_SCORE 
FROM 
(
    SELECT 
     QA.USER, 
     QA.TICKET_ID, 
     QA.TICKET_NUMBER, 
     SKILLS.AREA_ID, 
     SUM(QA.SCORE) AREA_SUM_SCORE 
    FROM 
     QA 
     INNER JOIN SKILLS ON SKILLS.SKILL_ID = QA.SKILL_ID 
     INNER JOIN TICKETS ON TICKETS.TICKET_ID = QA.TICKET_ID 
    GROUP BY 
     QA.USER, 
     QA.TICKET_ID, 
     QA.TICKET_NUMBER, 
     SKILLS.AREA_ID 
) AREAS_SCORES 

La sottoquery calcola la somma dei punteggi all'interno di ciascuna area per ogni ticket di ciascun utente. Quindi l'informazione viene aggregata di nuovo per contare la media ma con la restrizione che quando la somma dei punteggi per una particolare area supera 100, allora deve essere contata come 0.

Spero che sia utile in qualche modo (supponendo che ho capito bene il tuo problema).

+0

Ciao T_G, grazie mille, è fantastico! – ChrisA

+0

Ciao @Chris. Sono davvero contento che possa essere utile. Saluti :) –

1

Si può fare tutto ciò con una sola selezione.Si dovrà combinare il SUM con la CASE, in questo modo:

SELECT T.TICKET_NUMBER, 
SUM(CASE WHEN AREA_ID = 1 THEN QA.SCORE ELSE 0 END) SCORE_A1, 
SUM(CASE WHEN AREA_ID = 2 THEN QA.SCORE ELSE 0 END) SCORE_A2, 
SUM(CASE WHEN AREA_ID = 3 THEN QA.SCORE ELSE 0 END) SCORE_A3 
FROM QA INNER JOIN SKILLS S ON QA.SKILL_ID = S.SKILL_ID 
INNER JOIN TICKETS T ON QA.TICKET_ID = T.TICKET_ID 
WHERE QA.USER = :P2_USER GROUP BY T.TICKET_NUMBER 

Ora, applicare un ulteriore criterio per assicurarsi che la somma non va più di 100 l'uso di una query esterna:

SELECT TICKET_NUMBER, 
CASE WHEN SCORE_A1 > 100 THEN 0 ELSE SCORE_A1 END SCORE_A1, 
CASE WHEN SCORE_A2 > 100 THEN 0 ELSE SCORE_A2 END SCORE_A2, 
CASE WHEN SCORE_A3 > 100 THEN 0 ELSE SCORE_A3 END SCORE_A3 
FROM 
    (
    SELECT T.TICKET_NUMBER, 
    SUM(CASE WHEN AREA_ID = 1 THEN QA.SCORE ELSE 0 END) SCORE_A1, 
    SUM(CASE WHEN AREA_ID = 2 THEN QA.SCORE ELSE 0 END) SCORE_A2, 
    SUM(CASE WHEN AREA_ID = 3 THEN QA.SCORE ELSE 0 END) SCORE_A3 
    FROM QA INNER JOIN SKILLS S ON QA.SKILL_ID = S.SKILL_ID 
    INNER JOIN TICKETS T ON QA.TICKET_ID = T.TICKET_ID 
    WHERE QA.USER = :P2_USER GROUP BY T.TICKET_NUMBER 
    ) TIX 

e, infine, se hai bisogno di una media di questi tre punteggi utilizzare un altro livello di query esterne:

SELECT TICKET_NUMBER, 
SCORE_A1, 
SCORE_A2, 
SCORE_A3, 
(SCORE_A1+SCORE_A2+SCORE_A3)/3 AVG_SCORE 
FROM 
    (
    SELECT TICKET_NUMBER, 
    CASE WHEN SCORE_A1 > 100 THEN 0 ELSE SCORE_A1 END SCORE_A1, 
    CASE WHEN SCORE_A2 > 100 THEN 0 ELSE SCORE_A2 END SCORE_A2, 
    CASE WHEN SCORE_A3 > 100 THEN 0 ELSE SCORE_A3 END SCORE_A3 
    FROM 
     (
     SELECT T.TICKET_NUMBER, 
     SUM(CASE WHEN AREA_ID = 1 THEN QA.SCORE ELSE 0 END) SCORE_A1, 
     SUM(CASE WHEN AREA_ID = 2 THEN QA.SCORE ELSE 0 END) SCORE_A2, 
     SUM(CASE WHEN AREA_ID = 3 THEN QA.SCORE ELSE 0 END) SCORE_A3 
     FROM QA INNER JOIN SKILLS S ON QA.SKILL_ID = S.SKILL_ID 
     INNER JOIN TICKETS T ON QA.TICKET_ID = T.TICKET_ID 
     WHERE QA.USER = :P2_USER GROUP BY T.TICKET_NUMBER 
     ) TIX 
    ) MORE_TIX 
+0

Ciao Cha, incredibile, grazie mille !! – ChrisA