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

时间:2018-11-22 18:10:18

标签: sql oracle

当我尝试创建带有组函数条件和普通列条件的case表达式时,我遇到了问题。

表:STG

+ -------+--------+------+----------+
| Ref_ID | Actual | Paid | Reason   |
+ -------+--------+------+----------+
| 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  | TRAINING |
| 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

请提出您的建议。

1 个答案:

答案 0 :(得分:2)

根据业务规则,您始终希望在actual计算中包括sum(),但是仅当原因为paid时才包括'training'。该规则很容易在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
/

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