我有一个表MKT,其中包含以下字段value_date,stk_exch,security,mkt_price,source,currency,name
每天500个证券(不包括周六和周日以及其他市场假期)。
我需要一个sql来自动生成缺失日期和价格,从错误日期的前一个日期开始。因此,如果星期五是2013年7月26日,星期六和星期日是27日和28日,那么此表中将缺少第27和28日的日期和价格。
因此,虽然在2013年7月整个月的价格假设我应该得到所有日期和缺少日期,例如:27和28 sql将价格为26。
我正在使用Oracle
value_date stk_exch security mkt_price
-------------------------------------------------
26/07/2013 BSE BANKBARODA 565.85
29/07/2013 BSE BANKBARODA 585.85
现在SQL应该返回
value_date stk_exch security mkt_price
-------------------------------------------------
26/07/2013 BSE BANKBARODA 565.85
27/07/2013 BSE BANKBARODA 565.85
28/07/2013 BSE BANKBARODA 565.85
29/07/2013 BSE BANKBARODA 585.85
答案 0 :(得分:3)
我已将your_table用作outerjoin
的一个表,使用last_value
来插入以前的数据,
看看这个:)
SELECT last_value(m.data ignore nulls) over (order by n.mydate) data,
n.mydate
FROM
(SELECT DATA, mydate FROM your_table
) m,
(SELECT TRUNC(SYSDATE, 'MM')-1+LEVEL mydate FROM dual CONNECT BY LEVEL <= 30
)n
WHERE m.mydate(+) = n.mydate
ORDER BY n.mydate;
您也可以使用lag()
功能,但如果日期差距大于1,则不会填充数据。它只会填充以前的数据,
nvl(m.data, lag(m.data)over(order by n.mydate))
- 的编辑强> -
您的数据:
SELECT n.mydate VALUE_DATE,
last_value(m.STK_EXCH IGNORE NULLS) OVER (ORDER BY n.mydate) STK_EXCH,
last_value(m.SECURITY IGNORE NULLS) OVER (ORDER BY n.mydate) SECURITY,
last_value(m.mkt_price IGNORE NULLS) OVER (ORDER BY n.mydate) MKT_PRICE
FROM
(SELECT VALUE_DATE, STK_EXCH, SECURITY, MKT_PRICE FROM MKT
) m,
(SELECT TRUNC(SYSDATE, 'MM')-1+LEVEL mydate FROM dual CONNECT BY LEVEL <= 30
)n
WHERE TRUNC(m.VALUE_DATE(+)) = TRUNC(n.mydate)
ORDER BY n.mydate;
或更具体一点:使用以下:
SELECT full_date,
NVL(stk_exch,last_value(stk_exch IGNORE NULLS)OVER(ORDER BY full_date))stk_exch,
NVL(security,last_value(security IGNORE NULLS)OVER(ORDER BY full_date))security,
NVL(mkt_price,last_value(mkt_price IGNORE NULLS)OVER(ORDER BY full_date))mkt_price
FROM
(SELECT TRUNC(m.vd,'MM')-1+LEVEL FULL_DATE
FROM
(SELECT MIN(VALUE_DATE) vd FROM mkt
WHERE TO_CHAR( value_date, 'MM/YYYY') = TO_CHAR(sysdate-12,'MM/YYYY') -- this line may vary to your requirement
) m
CONNECT BY LEVEL <= TO_CHAR(LAST_DAY(M.VD), 'DD')
)first_q,
( SELECT value_date, stk_exch, SECURITY, mkt_price FROM mkt
)r
WHERE first_q.full_date = TRUNC(r.value_date(+))
ORDER BY full_date;