2017-06-19 66 views
0

我为铁路公司开发应用程序。我有一个问题来计算具体条件的平均值。 为了更好地理解我举一个例子平均条件和订单特定Oracle

下面是从数据库中的数据的一个例子:

---------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列的平均值。 然而,一个月后,情况有所改变。 如果只有系列具有相同的例程=相同的理论时间(列检查),那么我需要计算列HR的平均值3工作站

在此示例中,系列7100针对日期07具有不同的计划行程/ 12/2016在B站和C站,那么我只需要计算出2016年6月12日和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年7月12日。

是否有可能检查每一天如果该系列具有相同的路线/相同的时间为两个站 - >然后计算平均? 或者是否有可能将每天的例程昏迷到参考日?

这里是我的代码:

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

问题。 “check”的数据类型是什么(错误的列名称,它与Oracle关键字冲突)和“hr”?它们是否应该全部在同一天(或者是与任何特定日期无关的抽象时间)?那么 - 您当前的查询有什么问题,您丢失了哪些信息? – mathguy

+0

Redha Ben我想知道为什么'HAVING COUNT(*)> 1'?这将结果集限制为只有'CHECK''SERIE'-'NAME'的相同组合出现多次的记录子集。我猜想,当只有一个代表时,你想避免平均一个项目,但是想知道你缺少的数据是否包含那些只出现一次的“CHECK''SERIE'-'NAME'?谢谢 – alexgibbs

+0

感谢人试图帮助我。我编辑帖子可以ü检查PLZ。 –

回答

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