创建案例表达式时出现问题

Posted

技术标签:

【中文标题】创建案例表达式时出现问题【英文标题】:Issue while creating case expression 【发布时间】:2018-11-22 18:10:17 【问题描述】:

当我尝试使用组函数条件和普通列条件创建案例表达式时遇到问题。

表:STG

+ --------+--------+------+----------+ | Ref_ID |实际 |付费 |原因 | + --------+--------+------+----------+ | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 0 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 0 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 0 | 480 |培训 | | H1 | 0 | 0 | | | H1 | 360 | 0 | | | H1 | 360 | 0 | | + --------+--------+------+----------+

代码如下:

说明:如果每天的实际小时数超过 480,则需要将其视为 480。即。 8 小时/天 * 60 =480。 那么实际总和被延长1440然后需要从实际小时总和中扣除。

在同一个查询中,我必须将所有实际值与付费相加(如果原因是培训,则为付费小时)

 SELECT
    CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))>1440 THEN
    ((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))-1440) ELSE 0
    END SINGLE_RATE
    FROM STG WHERE REF_ID='H1'
    GROUP BY REF_ID;

我尝试修改如下:

SELECT
    CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))>1440 THEN
    ((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))-1440) ELSE 0
    END SINGLE_RATE
    FROM STG WHERE REF_ID='H1'
    GROUP BY REF_ID;

但出现以下错误:

    ORA-00979: not a GROUP BY expression
    00979. 00000 -  "not a GROUP BY expression"
    *Cause:
    *Action:

也尝试过:

SELECT
    (sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )-1440) SINGLE_RATE
    FROM STG WHERE REF_ID='H1'
    GROUP BY REF_ID
    having sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )>1440;

paid 的金额没有得到计算。只添加了actual

请提出您的建议。

【问题讨论】:

你可以参考这个:***.com/questions/11325268/… 感谢您的快速回复 Namandeep.. 编辑了我的问题。请帮帮我。 你有什么问题?你试图做什么,有什么问题?您可以在问题中包含您想要的结果;如果您的查询得到了错误的结果,您也可以将其包括在内,并解释其中的问题。 感谢 Alex 完美地编辑了我的问题。 【参考方案1】:

根据您的业务规则,您始终希望在 sum() 计算中包含 actual,但仅当原因为 'training' 时才包含 paid。该规则很容易在case 语句中表达。此外,您还有一个上限,actual 不能超过 480。该规则可以通过 least() 函数来满足:

select ref_id
      , sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
/

坦率地说,我仍然不清楚你想用 1440 实现什么;如果您发布了一些示例数据,涵盖了您想要处理的所有案例,并且您想要的输出来自该示例数据,那么生活会更轻松。但无论如何我都会猜测:

with cte as (
    select ref_id
          , sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
    from stg
    group by ref_id
    )
select ref_id
       case 
          when tot <= 1440 then tot
          else tot - 1440
       end as adjusted_tot
from cte
/

和以前一样,如果这不能提供您想要的答案,请编辑您的问题。您的要求越明确,您就越有可能得到及时的答复。

【讨论】:

谢谢 APC。因为我没有办公室笔记本电脑,所以我只是用我的个人笔记本电脑试了一下。结果如我所料。但是,我明天在办公室试试这个,然后告诉你它是否有效。很抱歉让你混淆了。但是,不知道如何解释我的问题。所以,我的问题非常混乱。非常感谢您的回复。 您好 APC,我已尝试使用您的建议代码。但这不是我想要的锻炼。还编辑了我的问题。但请检查并提出您的建议。 我试过如下。它给出了预期的结果:6240。但是,我必须尝试这个内部包。谢谢APC。用 cte 作为(选择 ref_id,总和(最小(实际,480))作为总和(支付)从 stg 支付,其中 payroll_ref='H1' 按 ref_id 分组),cte1 作为(选择 ref_id,总和(支付)作为从 stg 支付,其中 ref_id='H1' 和 reason='TRAINING' group by ref_id )选择 case when (cte.tot+cte1.paid) 在Thorsten的建议下,我才注意到这个案子。因此,我只是在您建议的代码中将原因更改为大写。现在,多数民众赞成在按预期工作。我会在包装中尝试这个。真的谢谢APC。与 cte 作为(选择 ref_id ,总和(最少(实际,480)+ case when reason='TRAINING' then paid else 0 end)作为 tot from stg where ref_id='H1' group by ref_id )选择 ref_id,当 tot 我们可以在打包过程中调用SQL。只需选择与查询的投影相匹配的 INTO 变量(或记录变量)。 PL/SQL 文档和这个站点确实充斥着示例,如果您自己无法弄清楚的话。

以上是关于创建案例表达式时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

oracle创建实例时出现ORA- 00922缺失或无效,忽略后出现ORA-28000账号已被锁定。

在 CREATE VIEW 内的 WITH...AS 中使用多个表表达式时出现“找不到对象”错误

使用 sysdate 创建默认列,但在插入数据时出现字符变化错误

使用正则表达式向 pdf 页面添加注释时出现 Swift 问题

使用 select-object @name="Name"; 时出现问题表达式=$变量

比较两个 typeid 表达式是不是相等时出现编译器错误