案例语句中的 ORACLE 总和

Posted

技术标签:

【中文标题】案例语句中的 ORACLE 总和【英文标题】:ORACLE sum inside a case statement 【发布时间】:2016-10-19 16:38:23 【问题描述】:

嗨,我需要这个结果。因此,如果 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

【问题讨论】:

尝试使用与as 不同的名称。这是一个关键字,它可能会混淆编译器。 【参考方案1】:

以及@GordonLinoff(即AS是关键字)和@DCookie(你需要在group-by中的entityid)提到的问题:

您还需要在 group-by 中使用 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 分支可以合并,因为计算是相同的,但无论哪种方式都可以。

【讨论】:

谢谢亚历克斯!非常好的解释,它奏效了! 在完成查询之后(这是一个子查询)我意识到使用 case 语句时效果更好: sum(CASE WHEN ufr.entityid = 'AHT' THEN MADAC.acdcalls + MADAC.daacdcalls WHEN ufr.entityid = 'ACW' THEN MADAC.acdcalls + MADAC.daacdcalls WHEN ufr.entityid = 'Adherence ' THEN MAAC.totalSched WHEN ufr.entityid = 'Conformance' THEN MASC.MINUTES ELSE NULL END) AS 重量【参考方案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

【讨论】:

以上是关于案例语句中的 ORACLE 总和的主要内容,如果未能解决你的问题,请参考以下文章

Oracle Apex - where 语句中的案例

Oracle SQL 中的复杂案例语句

Oracle 中的案例语句显示所有内容而不是查询项

Oracle SQL:案例语句

如何在Oracle中的case语句中添加两个用逗号分隔的引号的字符

常用sql语句及案例(oracle)