2015-01-29 12 views
5

Próbuję wykonać następujące czynnościAVG z 3 SELECT z GROUP BY

Mam QA stołowego, który zawiera następujące elementy:

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 

zakresu umiejętności stołowych wykonanych z:

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 

i a BILETY stołowe wykonane z:

TICKET_ID TICKET_NUMBER 
    1   AAA 
    2   BBB 
    3   CCC 

QA ma FK wejściówki korzystających TICKET_ID a także FK umiejętnościom korzystających SKILL_ID

Co musiałbym zrobić, to:

dla każdego biletu w ryzach stół QA że suma punktacji w każdej dziedzinie robi nie przekroczyć 100, a jeśli zostanie policzone jako 0, należy wykonać AVG z 3 wyników i pogrupować według numeru biletu, który znajduje się w innej tabeli Tak więc dla każdego przypadku musiałbym liczyć wynik dla każdego obszaru, jeżeli> 100 to 0 else pozostaw oryginalną wartość, a następnie zrób średnią z 3 wartości i zgrupuj według numeru biletu

Nie jestem pewien, czy jest to możliwe

Więc może obliczyć wynik area_1 I wykonaj następujące czynności:

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 

obliczyć wynik area_2 samo, ale zmianę warunku WHERE (gdzie AREA_ID = 2 to czas):

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 

i obliczyć wynik area_3 samo, ale zmienia się stan, w którym (gdzie 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 

Każdy t jego bloki daje wartość 1 jako wyjście

Co staram się osiągnąć to, mając jako wyjście AVG z 3 bloków przez ticket_number

starałem się zsumować 3 bloki wszystko razem, ale nie pozwala mi :

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 

Dziękuję

+0

Zwróć uwagę, że ze swojej wypowiedzi DECODE, czy 100 - SUM (SCORE) nie jest podzielna o 5, w wyniku tego pojawi się ZERO. To znaczy. jeśli 100 - SUMA (WYNIK) = 73, będzie 0. Czy tego oczekujesz? – cha

+0

Czy możesz potwierdzić, że używasz Oracle (funkcja 'DECODE')? –

+0

Cześć, dziękuję za odpowiedź, używam oracle 12c, więc tak, to jest funkcja dekodowania Oracle. Jak sprawdziłbyś, zamiast korzystać z funkcji dekodowania? Zauważyłem, że można osadzić skrzynkę w selekcji, ale głównym problemem jest to, że nie wiem, jak umieścić wszystko, aby uzyskać średnią z 3 obszarów dla każdego numeru biletu. Dziękujemy – ChrisA

Odpowiedz

3

spróbuj następujące zapytanie:

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 

Podzapytowanie oblicza sumę punktów w każdym obszarze dla każdego biletu każdego użytkownika. Następnie informacje są ponownie agregowane w celu zliczenia średniej, ale z ograniczeniem, że suma wyników dla określonego obszaru przekracza 100, wówczas należy ją liczyć jako 0.

Mam nadzieję, że pomoże to w pewien sposób (zakładając, że dobrze zrozumiałem Twój problem).

+0

Cześć T_G, wielkie dzięki, to niesamowite! – ChrisA

+0

Hi @Chris. Cieszę się, że może się przydać. Pozdrawiam :) –

1

Możesz to zrobić za pomocą jednego wyboru.trzeba będzie połączyć SUM z CASE coś takiego:

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 

Teraz, aby zastosować dodatkowe kryteria, aby upewnić się, że suma nie wykracza ponad 100 użyć zewnętrznego zapytania:

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 

i wreszcie, jeśli potrzeba średnio trzech punktów użyć innego poziomu zapytań zewnętrznych:

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

Cześć Cha, niesamowita, dzięki milion! – ChrisA