【问题标题】:AVG of 3 SELECT statements with GROUP BY使用 GROUP BY 的 3 个 SELECT 语句的平均值
【发布时间】:2015-01-29 23:27:31
【问题描述】:

我正在尝试执行以下操作

我有一个 QA 表,其中包含以下内容:

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

一张桌子 SKILLS 由:

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

还有一张由以下材料制成的 TICKETS 表:

  TICKET_ID   TICKET_NUMBER   
    1           AAA
    2           BBB
    3           CCC

QA 有一个使用 TICKET_ID 的 TICKETS 的 FK 和一个使用 SKILL_ID 的 SKILLS 的 FK

我需要做的是:

对于表 QA 中的每张工单,检查每个区域的得分总和是否超过 100,如果超过计为 0,则将 3 个结果的 AVG 并按另一个表中的工单号分组 因此,对于每种情况,我都需要计算每个区域的分数,如果 > 100 然后 0 则保留原始值,然后取 3 个值的平均值并按票号分组

不确定是否可行

所以也许要计算 area_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 = 1) AND TICKET_NUMBER = :P2_TICKET_NUMBER AND QA.USER = :P2_USER GROUP BY 1

计算area_2的分数相同但改变WHERE条件(这次WHERE AREA_ID = 2):

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

并计算 area_3 的分数,但改变 WHERE 条件(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

每个块都给出 1 个值作为输出

我想要实现的是通过 ticket_number 输出 3 个块的 AVG

我试图将 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 = 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

谢谢

【问题讨论】:

  • 请注意,如果您的 100 - SUM(SCORE) 不能被 5 整除,则使用您的 DECODE 表达式,结果将是零。 IE。如果 100 - SUM(SCORE) = 73 将是 0。这是您所期望的吗?
  • 您能否确认您使用的是 Oracle(DECODE 函数)?
  • 您好,感谢您的回复,我使用的是 oracle 12c,所以是的,它是 oracle 解码功能。您将如何检查而不是使用解码功能?我已经看到您可以在选择中嵌入一个案例,但主要问题是我不知道如何将所有内容放在一起以获得每个票号的 3 个区域的平均值谢谢
  • @ChrisA。嗨,请在下面找到答案。我希望你能得到需要的帮助。问候
  • 请通过edit 向您的问题添加信息,而不是将其埋在可能丢失在混乱中的cmets 中。它还有助于,特别是对于 SQL,包括您正在使用的特定 DBMS 的标签,因为它们之间的功能和语法各不相同。此外,您的问题标题中的信息也不必大喊。

标签: sql oracle


【解决方案1】:

请尝试以下查询:

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

子查询为每个用户的每张票计算每个区域内的分数总和。然后再次汇总信息以计算平均值,但限制是当特定区域的分数总和超过100,则应计为0

我希望它在某种程度上有所帮助(假设我很好地理解了你的问题)。

【讨论】:

  • 嗨@Chris。我真的很高兴它可能有用。问候:)
【解决方案2】:

您只需一次选择即可完成所有操作。您必须将SUMCASE 结合起来,如下所示:

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

现在,要应用附加条件以确保 SUM 不超过 100,请使用外部查询:

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

最后,如果您需要这三个分数的平均值,请使用另一个级别的外部查询:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 2011-01-28
    • 1970-01-01
    • 2017-12-09
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多