Условная арифметика Oracle SQL - PullRequest
0 голосов
/ 04 января 2019

У меня есть набор данных, в котором перечислены идентификатор сотрудника, код, часы и заработная плата.Любой 1 сотрудник может иметь 1 из OT1 или OT2, или они могут иметь по 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 голосов
/ 04 января 2019

Это можно сделать с помощью условного агрегирования:

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;

Этот метод явно объединяет значения из нескольких строк, поэтому он должен работать, как ожидается, при наличии дубликатов.

0 голосов
/ 04 января 2019

Вы получите часы для первого кода с 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;
...