SQL 自动为表中的缺失日期从前一个日期生成缺失的日期和价格
Posted
技术标签:
【中文标题】SQL 自动为表中的缺失日期从前一个日期生成缺失的日期和价格【英文标题】:SQL to automatically generate missing dates and price from immediately previous date for missing date in table 【发布时间】:2013-07-30 06:25:30 【问题描述】:我有一个 MKT 表,其中包含以下字段 value_date,stk_exch,security,mkt_price,source,currency,name
比如说每天 500 只证券(不包括周六和周日以及其他市场假期)。
我需要一个 sql 来自动生成缺失日期和缺失日期的前一个日期的价格。因此,如果星期五是 26.07.2013,星期六和星期日是 27 日和 28 日,则此表中将缺少 27 日和 28 日的日期和价格。
因此,在计算 2013 年 7 月整个月的价格时,我应该获取所有日期和缺失日期,例如:27 和 28,sql 将采用 26 日的价格。
我正在使用甲骨文
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
【问题讨论】:
您使用的是哪个 RDMS? 嗨,在这里查看更新的小提琴sqlfiddle.com/#!4/9fbaf/3/0 【参考方案1】:我将 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;
fiddle here
你也可以使用lag()
函数,但是如果日期间隔大于一个,它不会填充数据,它只会填充之前的数据,
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;
see fiddle here
【讨论】:
对不起,我没有完全得到这个查询来调整它。你能使用我在查询中提到的字段吗?谢谢 你能把你的数据样本贴出来,这样我就可以轻松地制作代码了。 嗨,我会尝试并恢复 您好 Ajmal,抱歉无法正常工作。它太复杂了,我无法理解和编辑它。任何其他选项 要么你只看到小提琴链接,要么考虑每天插入空值,不管它是否工作。所以查询起来很容易。以上是关于SQL 自动为表中的缺失日期从前一个日期生成缺失的日期和价格的主要内容,如果未能解决你的问题,请参考以下文章
SQL - 为表中的每个货币代码(在两个定义的日期之间)创建一个具有唯一日期和货币记录的表