Oracle SQL 条件算术
Oracle SQL Conditional Arithmetic
我有一个数据集,其中列出了员工 ID、代码、工时和工资。任何 1 名员工都可以有 1 个 OT1 或 OT2,或者他们可以有 1 行两者。简而言之,我需要将所有工资相加,但如果他们有两个代码,则只需计算 OT1 的金额。然后我想在我陈述的条件下将总工资除以小时数。示例数据:
+ ------+------+--------+--------+
|编号 |代码 |营业时间 |金额 |
+ ------+------+--------+--------+
| 123456 | OT1 | 10 | 80 |
| 789000 | OT1 | 8 | 120 |
| 789000 | OT2 | 8 | 60 |
| 654111 | OT2 | 4 | 40 |
+ ------+------+--------+--------+
我正在尝试添加一个新列以将金额除以小时数,并将删除代码列,以便我们可以对每个员工求和以获得单个记录。问题是,如果员工同时拥有 OT1 和 OT2,我不想将它们相加,我只想要 OT1 的小时数。该逻辑手动应用于我之前的示例
+ ------+--------+--------+--------+
|编号 |营业时间 |金额 |平均值 |
+ ------+--------+--------+--------+
| 123456 | 10 | 80 | 8 |
| 789000 | 8 | 180 | 22.5 |
| 654111 | 4 | 40 | 10 |
+ ------+--------+--------+--------+
您获得了使用 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;
您可以使用条件聚合来做到这一点:
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;
此方法显式组合了多行的值,因此如果存在重复值,它应该会按预期工作。
我有一个数据集,其中列出了员工 ID、代码、工时和工资。任何 1 名员工都可以有 1 个 OT1 或 OT2,或者他们可以有 1 行两者。简而言之,我需要将所有工资相加,但如果他们有两个代码,则只需计算 OT1 的金额。然后我想在我陈述的条件下将总工资除以小时数。示例数据:
+ ------+------+--------+--------+ |编号 |代码 |营业时间 |金额 | + ------+------+--------+--------+ | 123456 | OT1 | 10 | 80 | | 789000 | OT1 | 8 | 120 | | 789000 | OT2 | 8 | 60 | | 654111 | OT2 | 4 | 40 | + ------+------+--------+--------+
我正在尝试添加一个新列以将金额除以小时数,并将删除代码列,以便我们可以对每个员工求和以获得单个记录。问题是,如果员工同时拥有 OT1 和 OT2,我不想将它们相加,我只想要 OT1 的小时数。该逻辑手动应用于我之前的示例
+ ------+--------+--------+--------+ |编号 |营业时间 |金额 |平均值 | + ------+--------+--------+--------+ | 123456 | 10 | 80 | 8 | | 789000 | 8 | 180 | 22.5 | | 654111 | 4 | 40 | 10 | + ------+--------+--------+--------+
您获得了使用 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;
您可以使用条件聚合来做到这一点:
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;
此方法显式组合了多行的值,因此如果存在重复值,它应该会按预期工作。