Oracle SQL条件运算

时间:2019-01-04 06:14:06

标签: sql oracle conditional

我有一个数据集,其中列出了员工ID,代码,工时和工资。任何1名员工都可以同时拥有OT1或OT2中的1名,或者两者都有1行。简而言之,我需要将所有工资加起来,但是如果它们都有这两个代码,就只能算出OT1的金额。然后,我要按我所说的条件将总工资除以小时数。示例数据:

+ -------+------+-------+--------+
| ID     | CODE | HOURS | AMOUNT |
+ -------+------+-------+--------+
| 123456 | OT1  | 10    | 80     |
| 789000 | OT1  | 8     | 120    |
| 789000 | OT2  | 8     | 60     |
| 654111 | OT2  | 4     | 40     |
+ -------+------+-------+--------+

我正尝试添加一个新列以按小时数除以金额,并将删除代码列,以便我们可以将每个员工的总和汇总为一条记录。问题是,如果员工同时拥有OT1和OT2,我不想将它们加总,我只想从OT1开始的时间。该逻辑手动应用于我之前的示例

+ -------+-------+--------+---------+
| ID     | HOURS | AMOUNT | AVERAGE |
+ -------+-------+--------+---------+
| 123456 | 10    | 80     | 8       |
| 789000 | 8     | 180    | 22.5    |
| 654111 | 4     | 40     | 10      |
+ -------+-------+--------+---------+

2 个答案:

答案 0 :(得分:0)

您将获得使用Oracle KEEP FIRST进行第一个代码的时间:

select
  id, 
  min(hours) keep (dense_rank first order by code) as hours,
  sum(amount) as amount,
  round(sum(amount) / min(hours) keep (dense_rank first order by code), 2) as average
from mytable
group by id
order by id;

答案 1 :(得分:0)

您可以使用条件聚合来做到这一点:

select id, 
       coalesce(sum(case when code = 'OT1' then hours end),
                sum(hours)
               ) as hours,
       sum(amount) as amount,
       (sum(amount) / 
        coalesce(sum(case when code = 'OT1' then hours end),
                 sum(hours)
               )
       ) as average
from t
group by id
order by id;

此方法显式组合了多行中的值,因此,如果有重复项,它应该可以按预期工作。