我在项目中跟踪了一些指标,其值随着时间的推移而不断增加。
示例数据:
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月份没有发生任何测量。
您能就解决此问题发表一些意见吗?
答案 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