ORACLE在案例陈述中总结

时间:2016-10-19 16:38:24

标签: sql oracle sum case

嗨,我需要这个结果。所以如果一个entityID匹配一个值,我需要某个列的总和。我得到一个表达式丢失错误。有人能指出我的错误在哪里吗? 感谢。

                   SELECT                               
                            p.jobTitle,
                            p.department,
                            p.person,
                            ufr.meets,
                            ufr.exceeds,
                            CASE 
                                 WHEN ufr.entityid = 'AHT' THEN (AD.acdcalls + AD.daacdcalls) 
                                 WHEN ufr.entityid = 'ACW' THEN (AD.acdcalls + AD.daacdcalls) 
                                 WHEN ufr.entityid = 'Adherence' THEN SUM(AA.totalSched)
                                 WHEN ufr.entityid = 'Conformance' THEN SUM(AS.minutes)
                                 ELSE null
                            END as weight,
                            (weight * meets) AS weightedMeets,
                            (weight * exceeds) AS weightedExceeds

                    FROM  M_PERSON p
                    JOIN A_TMP5408_UNFLTRDRESULTSAG ufr
                            ON ufr.department = p.department AND ufr.jobTitle = p.jobTitle 
                    LEFT JOIN M_AvayaDAgentChunk AD 
                            ON AD.person = p.person and ufr.split = AD.split    
                    LEFT JOIN M_AgentAdherenceChunk AA 
                            ON AA.person = p.person 
                    LEFT JOIN M_AgentScheduleChunk AS 
                            ON AS.person = p.person 

                    GROUP BY
                            p.person,
                            p.department,
                            p.jobTitle,
                            ufr.meets,
                            ufr.exceeds,
                            weight,
                            weightedMeets,
                            weightedExceeds

2 个答案:

答案 0 :(得分:2)

除了Gordon发现的别名问题之外,我认为您还需要在CASE语句的所有THEN子句中使用聚合函数,并且还需要GROUP BY ufr.entityid 。否则,您将开始收到ora-00979错误(不是GROUP BY表达式)。如果您不想在所有条款中使用聚合函数,那么您必须按照您要求求和的表达式进行分组。

小插图:

CREATE TABLE tt (ID varchar2(32), sub_id varchar2(32), x NUMBER, y NUMBER);
INSERT INTO tt VALUES ('ID1', 'A', 1, 6);
INSERT INTO tt VALUES ('ID1', 'B', 1, 7);
INSERT INTO tt VALUES ('ID2', 'A', 2, 6);
INSERT INTO tt VALUES ('ID2', 'B', 2, 7);
INSERT INTO tt VALUES ('ID3', 'A', 3, 6);
INSERT INTO tt VALUES ('ID3', 'B', 3, 7);
INSERT INTO tt VALUES ('ID3', 'C', 3, 8);

SELECT ID, CASE WHEN sub_id = 'A' THEN SUM(y)
                WHEN sub_id = 'B' THEN SUM(x)
                ELSE (x + y) END tst
  FROM tt
 GROUP BY ID

ORA-00979: not a GROUP BY expression  (points at sub_id in WHEN)

SELECT ID, CASE WHEN sub_id = 'A' THEN SUM(y)
                WHEN sub_id = 'B' THEN SUM(x)
                ELSE (x + y) END tst
  FROM tt
 GROUP BY ID, sub_id

ORA-00979: not a GROUP BY expression    (points at x in ELSE)

SQL> SELECT ID, CASE WHEN sub_id = 'A' THEN SUM(y)
  2                  WHEN sub_id = 'B' THEN SUM(x)
  3                  ELSE SUM(x + y) END tst
  4    FROM tt
  5   GROUP BY ID, sub_id;

ID                                      TST
-------------------------------- ----------
ID1                                       6
ID3                                       6
ID3                                       3
ID1                                       1
ID2                                       6
ID2                                       2
ID3                                      11

答案 1 :(得分:2)

除了@GordonLinoff提到的问题(AS是关键字)和@DCookie(在分组中你需要entityid):

  • 您还需要分组中的acdcallsdaacdcalls(除非您可以汇总这些内容);
  • 您无法在同一级别的查询中引用列别名,因此不允许(weight * meets) AS weightedMeets - 您只需定义weight是什么,相同的选择列表。如果您不想重复case逻辑,则需要使用内联视图或CTE。

我认为这可以满足您的需求:

SELECT
        jobTitle,
        department,
        person,
        meets,
        exceeds,
        weight,  
        (weight * meets) AS weightedMeets,
        (weight * exceeds) AS weightedExceeds
FROM
(
        SELECT                               
                MP.jobTitle,
                MP.department,
                MP.person,
                ufr.meets,
                ufr.exceeds,
                CASE 
                     WHEN ufr.entityid = 'AHT' THEN (MADAC.acdcalls + MADAC.daacdcalls) 
                     WHEN ufr.entityid = 'ACW' THEN (MADAC.acdcalls + MADAC.daacdcalls) 
                     WHEN ufr.entityid = 'Adherence' THEN SUM(MAAC.totalSched)
                     WHEN ufr.entityid = 'Conformance' THEN SUM(MASC.minutes)
                     ELSE null
                END as weight
        FROM  M_PERSON MP
        JOIN A_TMP5408_UNFLTRDRESULTSAG ufr
                ON ufr.department = MP.department AND ufr.jobTitle = MP.jobTitle 
        LEFT JOIN M_AvayaDAgentChunk MADAC 
                ON MADAC.person = MP.person and ufr.split = MADAC.split    
        LEFT JOIN M_AgentAdherenceChunk MAAC
                ON MAAC.person = MP.person 
        LEFT JOIN M_AgentScheduleChunk MASC
                ON MASC.person = MP.person 
        GROUP BY
                MP.person,
                MP.department,
                MP.jobTitle,
                ufr.meets,
                ufr.exceeds,
                ufr.entityid,
                MADAC.acdcalls,
                MADAC.daacdcalls
);

你的第一个case分支可以合并,因为计算是相同的,但无论哪种方式都可以。