Oracle分析功能建议

时间:2015-05-14 18:15:57

标签: sql oracle window-functions

我在项目中跟踪了一些指标,其值随着时间的推移而不断增加。

示例数据:

IntSummaryStatistics{count=10, sum=129, min=2, average=12.900000, max=29}

我需要月份明智的有效价值,如下所示。如果在该月的第1天有一个度量值,则使用它,否则使用上个月的最后一个测量值。

 Project | Date        | Metric%
---------------------------------
  P1     | 05-Jan-2015 |  40
  P1     | 10-Jan-2015 |  50
  P1     | 05-Feb-2015 |  60
  P1     | 01-Mar-2015 |  70
  P1     | 25-Mar-2015 |  80
  P1     | 03-Apr-2015 |  90

我正在使用下面的sql来获取此信息:

 Project | Month Start Date | Effective Metric%
------------------------------------------------
   P1    | 01-Feb-2015      |   50
   P1    | 01-Mar-2015      |   70
   P1    | 01-Apr-2015      |   80
   P1    | 01-May-2015      |   90

上述查询未向我提供select sq2.project_id, sq2.mon_start_dt, sq2.metric_value from (select sq1.project_id, trunc(sq1.metric_measurement_dt, 'MONTH') mon_start_dt, -- gives date in the format 01MMYYYY /* Check if metric_measurement_dt is 1st day of month (01MMYYYY), if so use the metric value else use previous metric value */ case when extract(day FROM sq1.metric_measurement_dt) = 1 then sq1.metric_current_val else sq1.metric_previous_val end metric_value, from ( /* Get current and previous metric values for all measurement dates */ select project_id, metric_measurement_dt, row_number() over (partition by project_id, extract(month from metric_measurement_dt) order by metric_measurement_dt) mm_start_row, metric_value metric_current_val, lag(metric_value) over (partition by project_id order by metric_measurement_dt) metric_previous_val, from table t1 ) sq1 where sq1.mm_start_row = 1) sq2 where sq2.metric_value is not null; 行。我相信这是因为5月份没有发生任何测量。

您能就解决此问题发表一些意见吗?

2 个答案:

答案 0 :(得分:1)

这是另一种方法。对于每条记录,获取当前值和先前值。此外,枚举一个月内的值。然后,选择月中的第一个值。如果该月的日期为“1”,则取当前值。否则,取以前的值:

select project_id, trunc(metric_measurement_dt, 'MONTH') as mon,
       (case when extract(day from metric_measurement_dt) = 1 then metric_value
             else prev_value
        end) as metric_value
from (select project_id, metric_measurement_dt, metric_value,
             row_number() over (partition by project_id, extract(month from metric_measurement_dt)
                                order by metric_measurement_dt) as seqnum,
             lag(metric_value) over (partition by project_id
                                     order by metric_measurement_dt) as prev_value
      from table t1 
     ) t
where seqnum = 1

答案 1 :(得分:-1)

LAST_DAY(dt-1)+1将下个月的第一天分配给每月不到一个月的日期。然后你只需应用ROW_NUMBER

SELECT *
FROM 
 (
   SELECT Project, Metric,
      LAST_DAY(dt-1)+1 AS dt,
      ROW_NUMBER() 
      OVER (PARTITION BY Project, LAST_DAY(dt-1)+1
            ORDER  BY dt DESC) AS rn
   FROM tab
 ) dt
WHERE rn = 1