Oracle SQL根据条件查找增量括号

ffdz8vbo  于 2023-05-28  发布在  Oracle
关注(0)|答案(3)|浏览(502)

我有一些这样的数据:

我的要求是根据用户的额外工作时间获得总工资。

with t as
 (select 1  from_hour,4  to_hour,20 pay from dual union all
  select 5  from_hour,8  to_hour,50 pay from dual union all
  select 10  from_hour,12  to_hour,100 pay from dual)
, input_data
as
(
select 6 user_hours from dual
)
select t.from_hour,t.to_hour,t.pay
  from t
  join input_data i on 1=1 
  ;

例如:

  • 当用户工作了4个小时,我们支付每小时20美元。总计= 4* 20 = 80$

  • 当用户工作了6个小时,我们支付前4小时20美元,然后为第5和第6小时,我们支付50美元。

  • 当用户工作了9个小时,前4个小时20美元,然后为第5至第8小时,我们支付50美元,为第9小时,我们支付100美元。

任何关于如何实现HOURS_WORKED列计算和上述数据集的指导都将非常有帮助。
谢谢。

yduiuuwa

yduiuuwa1#

这很简单:
DBFiddle:https://dbfiddle.uk/ovlq7ZjO

with t as
 (select 1  from_hour,4  to_hour,20 pay from dual union all
  select 5  from_hour,8  to_hour,50 pay from dual union all
  select 10  from_hour,12  to_hour,100 pay from dual)
, input_data
as
(
select 6 user_hours from dual
)
select *
  from input_data i
  outer apply(
     select 
        sum((least(t.to_hour,i.user_hours) - (t.from_hour-1) ) * t.pay) as sum_to_pay
     from t
     where i.user_hours>= t.from_hour
  );

或者解释一下:

with t as
 (select 1  from_hour,4  to_hour,20 pay from dual union all
  select 5  from_hour,8  to_hour,50 pay from dual union all
  select 10  from_hour,12  to_hour,100 pay from dual)
, input_data
as
(
select 6 user_hours from dual
)
select *
  from input_data i
  outer apply(
     select 
        (least(t.to_hour,i.user_hours) - (t.from_hour-1) ) as hours_to_pay
       ,(least(t.to_hour,i.user_hours) - (t.from_hour-1) ) * t.pay as sum_to_pay
       ,t.*
     from t
     where i.user_hours>= t.from_hour
  )
  ;

hours_to_pay-是一个小时数,我们通过比较user_hours和to_hour得到
使用outer applysum()来聚合结果

uttx8gqw

uttx8gqw2#

看起来你的“total_pay”列是从“hours_worked”列派生出来的,所以我们:

  • 首先使用带条件的CASE表达式计算工作时间
  • 然后我们应用“hours_worked”和相应的“pay”之间的乘积
WITH t AS (
  SELECT  1 from_hour,  4 to_hour,  20 pay FROM dual UNION ALL
  SELECT  5 from_hour,  8 to_hour,  50 pay FROM dual UNION ALL
  SELECT  9 from_hour, 12 to_hour, 100 pay FROM dual
), input_data AS (
  SELECT 6 user_hours FROM dual
)
SELECT t.from_hour,
       t.to_hour,
       t.pay,
       CASE WHEN t.to_hour <= i.user_hours THEN 4 
            ELSE i.user_hours - t.from_hour +1 
       END AS num_hours,
       t.pay * CASE WHEN t.to_hour <= i.user_hours THEN 4 
                    ELSE i.user_hours - t.from_hour +1 
               END AS total_pay
FROM       t
INNER JOIN input_data i
        ON t.from_hour <= i.user_hours

输出

| 开始_小时|至小时|支付|小时数|总计_支付|
| - -----|- -----|- -----|- -----|- -----|
| 一个|4|二十个|4|八十|
| 5个|八|五十|2|一百|
查看演示here

hfyxw5xn

hfyxw5xn3#

您可以使用相关子查询来查找工资总额:

select i.user_hours,
       ( SELECT SUM( (LEAST(i.user_hours, to_hour) - from_hour + 1) * pay )
         FROM   t
         WHERE  from_hour <= i.user_hours
       ) AS total_pay
from   input_data i;

其中,对于样本数据:

CREATE TABLE t (from_hour, to_hour, pay) AS
  select  1,  4,  20 from dual union all
  select  5,  8,  50 from dual union all
  select  9, 12, 100 from dual;

CREATE TABLE input_data (user_hours) AS
  select 6 user_hours from dual;

输出:
| 用户小时数|总计_支付|
| - -----|- -----|
| 六|一百八十|
fiddle

相关问题