我从银行系统获得以下数据:date, product code, due date.
我需要做的是向后填充每个产品due_dates
,即前几个月,但仅限于due_date <= date.
我还想在每个产品中填充max_date,这是最近的due_date的日期。
如您所见,我可能在一个产品中有许多due_dates或没有。
如果有多个日期,则不应覆盖之前的日期。
这就是现在的样子:
date product due_date
------------------------------------------
2012-01-31 a1
2012-02-28 a1
2012-01-31 b1
2012-02-28 b1
2012-03-31 b1
2012-04-30 b1 2012-02-18
2012-05-31 b1
2012-06-30 b1 2012-05-31
2012-07-31 b1
2012-08-31 b1
2012-09-30 b1 2012-09-01
2012-10-31 b1
2012-04-30 c1
2012-05-31 c1
2012-06-30 c1 2011-03-01
2012-07-31 c1
这是我想得到的结果:
date product due_date max_date
--------------------------------------------------------
2012-01-31 a1
2012-02-28 a1
2012-01-31 b1 2012-09-30
2012-02-28 b1 2012-02-18 2012-09-30
2012-03-31 b1 2012-02-18 2012-09-30
2012-04-30 b1 2012-02-18 2012-09-30
2012-05-31 b1 2012-05-31 2012-09-30
2012-06-30 b1 2012-05-31 2012-09-30
2012-07-31 b1 2012-09-30
2012-08-31 b1 2012-09-30
2012-09-30 b1 2012-09-01 2012-09-30
2012-10-31 b1 2012-09-30
2012-04-30 c1 2011-03-01 2012-06-30
2012-05-31 c1 2011-03-01 2012-06-30
2012-06-30 c1 2011-03-01 2012-06-30
2012-07-31 c1 2012-06-30
答案 0 :(得分:1)
请参阅SQL Fiddle
SELECT
t1.date_
, t1.product
, case
when t1.due_date is not null then t1.due_date
else (
select max(due_date)
from sot t2
where t2.product = t1.product
and t2.due_date <= t1.date_
and t2.date_ > t1.date_
)
end
as due_date
, t3.max_date
FROM
sot t1
left outer join ( select product, max(date_) keep (dense_rank first order by due_date desc) as max_date
from sot
where due_date is not null
group by product
) t3
on (t3.product = t1.product)
order by product, date_;
due_date的计算表现不佳,但我目前没有看到更好的替代方案
答案 1 :(得分:1)
尝试使用此查询可能会有用,适用于您的数据示例,(您可以尝试 here ):
WITH temp1 AS (
SELECT ROW_NUMBER() OVER (PARTITION BY product ORDER BY date_f,product ASC) AS row_num,
date_f,
product,
due_date
FROM TEST
), temp2 AS (
SELECT row_num,date_f,product, due_date FROM temp1 WHERE NOT due_date IS NULL
), temp3 AS (
SELECT product, MAX(date_f) AS max_due_date
FROM TEST
WHERE NOT due_date IS NULL
GROUP BY product
)
SELECT
to_char(a.date_f,'YYYY-MM-DD') AS DATE_F,
a.product,
to_char(NVL(a.due_date,
(SELECT MIN(b.due_date)
FROM temp2 b
WHERE b.product = a.product AND b.due_date <= a.date_f AND a.row_num < b.row_num)),'YYYY-MM-DD') AS due_date,
to_char(
(SELECT c.max_due_date FROM temp3 c
WHERE c.product = a.product AND ROWNUM = 1),'YYYY-MM-DD') AS max_date
FROM temp1 a
注意:目前我无法做得更好:(