困难的SQL问题

时间:2013-09-20 14:38:44

标签: sql oracle

请记住,这需要在SQL中完成 - 而不是PL / SQL,而不是在这里播放循环。

我需要从一个数量的单行,到多个行,数量分散。这是详细信息;

我有一条规则,即当一名员工缺席一段时间时,奖励代替时间。但是,此规则会在该期间的最后一天奖励所有小时,并且客户希望它在8小时/天内分散。

例如,如果EE短25小时 - 现有规则将在该期间的最后一天授予25小时。客户要求最后一天8小时,最后一天8小时,最后一天8小时,最后一天4小时。

我的SQL很棒,但我在这个上面写了一个空白。有什么建议?同样,不允许PL / SQL或while循环,必须在SQL(Oracle)中完成。

示例数据

从这开始;

**ID Date        Amount**
1  09/30/2013  25

需要以此结束;

**ID Date        Amount**
1  09/30/2013  8
1  09/29/2013  8
1  09/28/2013  8
1  09/27/2013  1

2 个答案:

答案 0 :(得分:2)

如果这些期间对于单个员工不重叠,您也可以尝试这样的事情:

select  distinct id, "date"-(level-1) "date", least(amount-(level-1)*8, 8) amount
from    sample_data
connect by amount > (level-1)*8
order   by id, "date" desc

答案 1 :(得分:1)

如果您创建一个包含所有可能日期的表格,则可以交叉加入该表格。也许该表有一个实际的日期,但它每行还有一个日期编号:1,2,3,4 ......这就是你想要分配小时的顺序:即8小时到一天#1 ,任何剩余的(但最多8个)到第2天,依此类推。

对于任何特定的day_num,表达式((day_num - 1)* 8)将为您提供最大值。可以分配的小时数。只有当员工有超过这个时间的时候,这个特定的日子才能获得分配。此外,分配必须限制在8个。

SQL看起来如下所示。 (See this SQL fiddle for schema

select emp_id, total_hours, day_num,
       case 
          when total_hours - ((day_num-1) * 8) > 8 then 8
          when total_hours - ((day_num-1) * 8) < 0 then 0
          else total_hours - ((day_num-1) * 8) 
       end hours_for_day
from emp_short
cross join all_days
where total_hours - ((day_num-1) * 8) > 0