2015-01-29 15 views
5

Ich versuche, die folgendeAVG von 3 SELECT-Anweisungen mit GROUP BY

Ich habe eine Tabelle QA zu tun, die Folgendes enthält:

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 

einem Tisch SKILLS aus:

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 

und eine Tabelle TICKETS aus:

TICKET_ID TICKET_NUMBER 
    1   AAA 
    2   BBB 
    3   CCC 

QA hat eine FK auf TICKETS TICKET_ID mit und auch ein FK Fähigkeiten skill_id

Was würde ich tun müssen, ist:

für jedes Ticket in Prüftabelle QA, dass die Summe der Punkte in jedem Bereich tut nicht über 100 gehen und wenn über als eine 0 zählen, dann machen Sie die AVG der 3 Ergebnisse und gruppieren durch die ticket_number, die in einer anderen Tabelle ist Also für jeden Fall müsste ich die Punktzahl für jeden Bereich zählen, wenn> 100 dann 0 sonst lassen Sie den ursprünglichen Wert, dann machen Sie den Durchschnitt der 3 Werte und gruppieren Sie die Ticketnummer

Nicht sicher, ob dies möglich ist

vielleicht

So die Partitur von area_1 zu berechnen ich folgendes:

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 

die Partitur area_2 gleiche Sache zu berechnen, sondern die Änderung der WHERE-Bedingung (WHERE AREA_ID = 2 dieses Mal):

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 

und die Partitur area_3 gleichen Sache zu berechnen, aber die WHERE-Bedingung zu ändern (WHERE 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 

Jeder von t seine Blöcke gibt 1-Wert als Ausgangs

Was ich versuche als Ausgabe der 3 Blöcke die AVG zu erreichen, ist mit von ticket_number

ich alle zusammen die drei Blöcke zusammenzufassen versucht, aber es mir nicht erlaubt, :

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 

Danke

+0

Bitte beachten Sie, dass mit Ihrem DECODE Ausdruck, wenn Sie 100 - Summe (Punkte) nicht teilbar ist um 5 wird es eine ZERO geben. I.e. wenn 100 - SUMME (SCORE) = 73 wird es 0 sein. Ist das was du erwartest? – cha

+0

Können Sie bestätigen, dass Sie Oracle ('DECODE'-Funktion) verwenden? –

+0

Hallo, danke für die Antwort, ich benutze Oracle 12c, also ja, es ist die Orakel-Dekodierfunktion. Wie würden Sie überprüfen, anstatt die Dekodierungsfunktion zu verwenden? Ich habe gesehen, dass Sie einen Fall in eine Auswahl einbetten können, aber das Hauptproblem ist, dass ich nicht weiß, wie man alle zusammenstellt, um den Durchschnitt der 3 Bereiche für jede Ticketnummer zu haben. Danke – ChrisA

Antwort

3

Bitte versuchen Sie die folgende Abfrage:

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 

Die Unterabfrage berechnet die Ergebnissumme in jedem Bereich für jedes Ticket jedes Benutzers. Dann werden die Informationen erneut aggregiert, um den Durchschnitt zu zählen, jedoch mit der Einschränkung, dass, wenn die Summe der Bewertungen für einen bestimmten Bereich 100 übersteigt, dieser Wert als 0 gezählt werden sollte.

Ich hoffe, es hilft irgendwie (vorausgesetzt, ich habe Ihr Problem gut verstanden).

+0

Hallo T_G, vielen Dank, das ist super! – ChrisA

+0

Hallo @ Chris. Ich bin wirklich froh, dass es nützlich sein könnte. Grüße :) –

1

Sie können dies alles mit einer einzigen Auswahl tun.

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 

nun zusätzliche Kriterien anzuwenden, um sicherzustellen, dass die Summe nicht mehr als 100 Gebrauch geht eine äußere Abfrage: Sie werden die SUM mit dem CASE, wie diese kombinieren müssen

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 

und schließlich, wenn Sie einen Durchschnitt dieser drei Werte müssen verwendet eine andere Ebene der Außen Anfragen:

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

Hallo Cha, unglaublich, danke eine Million !! – ChrisA