具有条件和订单特定Oracle的平均值

时间:2017-06-19 17:59:46

标签: sql oracle conditional-statements average

我为铁路公司开发了一个应用程序。我有一个问题是计算特定条件的平均值。 为了更好地理解,我将举一个例子

以下是数据库中数据的示例:

---------check----------------HR---------------Serie-----NameStation

06/12/2016 05:57:00     06/12/2016 05:57:07     7100    Station A
06/12/2016 05:59:30     06/12/2016 05:59:40     7100    Station B
06/12/2016 06:00:00     06/12/2016 06:00:35     7100    Station C

07/12/2016 05:57:00     07/12/2016 05:56:34     7100    Station A
07/12/2016 06:00:30     07/12/2016 05:58:59     7100    Station B
07/12/2016 06:01:00     07/12/2016 05:59:46     7100    Station C

08/12/2016 05:57:00     08/12/2016 05:56:25     7100    Station A
08/12/2016 05:59:30     08/12/2016 05:59:28     7100    Station B
08/12/2016 06:00:00     08/12/2016 06:01:50     7100    Station C

我有一个月内每列火车的数据。 。 火车每天都有一个计划行程(它在指定时间通过3个车站=理论时间,即列检查,类型是日期dd/ mm/yyyy hh:mm:ss)。 我的人力资源专栏是列车真正在车站经过的时间=实时,其格式与检查栏相同。

我的目标是计算一个月内HR列的平均值。 然而,在一个多月的时间里,时间表发生了变化。 如果只有系列具有相同的例程= 3站的相同理论时间(列检查),我需要计算HR列的平均值

在这个例子中,系列7100在B和C站的日期为07/12/2016有不同的计划行程。然后我需要计算2016年12月6日和2016年12月8日的平均值。 分别为07/12/2016的平均值。 或者更好地计算最适合的计划行程的平均值(在列检查时同一时间站A + B + C)。

结果应该是

    check    HR       Serie     StationName
05:57:00    05:56:46    7100    Station A
05:59:30    05:59:34    7100    Station B
06:00:00    06:01:13    7100    Station C

05:57:00    05:56:34    7100    Station A
06:00:30    05:58:59    7100    Station B
06:10:00    05:59:46    7100    Station C

我尝试使用GROUP BY,但我丢失了一些信息,因为它会计算A站在2016年12月7日的平均值和其他天数。

是否可以检查每个系列是否具有相同的路线/同一时间的两个电台 - >然后计算平均值? 或者是否有可能将每天的例行程序推荐到参考日?

这是我的代码:

    SELECT check,
       TO_CHAR( TRUNC( SYSDATE ) + AVG( HR - TRUNC( HR ) ), 'HH24:MI:SS' )
         AS "AVG(HR)",
       serie,
       name
GROUP BY check, serie, name
HAVING COUNT(*) > 1

提前谢谢。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。

对于遇到同样问题的人: 解决方案是添加一个列,我将列的所有时间检查每一列(data_with_timelist)在每一行和我分组之后

with data as(    
    select t.*,    
    trunc(chck) chck_date,    
    numtodsinterval(chck-trunc(chck), 'DAY') chck_time,  
    dense_rank() over(partition by serie order by chck-trunc(chck)) dr  
    from t    
)    
, data_with_timelist as (    
    select d.*,    
    listagg(to_char(dr,'fm00X')) within group(order by dr) over(partition by serie, chck_date) dr_list    
    from data d    
)    
select serie, namestation,  
to_char(min(chck_date) + chck_time, 'hh24:mi:ss') chck_time,  
to_char(  
    cast(  
        to_timestamp(min(chck_date)) + chck_time + numtodsinterval(avg(hr-chck), 'DAY')  
        as timestamp(0)  
    )  
    , 'hh24:mi:ss'  
) avg_hr_time  
from data_with_timelist    
group by serie, dr_list, chck_time, namestation    
order by serie, dr_list, chck_time, namestation;  

     SERIE NAMESTATION            CHCK_TIM AVG_HR_T  
---------- ---------------------- -------- --------  
      7100 Station A              05:57:00 05:56:46  
      7100 Station B              05:59:30 05:59:34  
      7100 Station C              06:00:00 06:01:13  
      7100 Station A              05:57:00 05:56:34  
      7100 Station B              06:00:30 05:58:59  
      7100 Station C              06:10:00 05:59:46