sql填写缺失的数据?

时间:2015-05-08 20:50:56

标签: sql oracle

提供以下查询“

select ping_date,packet_loss,ping_avg,ping_source,ping_destination
from router_ping 
where ping_date > sysdate - NUMTODSINTERVAL (24, 'HOUR') AND (ping_source = 'zja68f-wr2' AND ping_destination = 'zja68f-wr2'  OR ping_source = 'zja68f-wr2' AND ping_destination = 'zja68f-wr2' )
order by TRUNC(ping_date), ping_date ASC

将输出:

 PACKET_LOSS    PING_AVG    PING_DATE   PING_DESTINATION    PING_SOURCE
0                 273   2015-05-07 17:40:16.0   zja68f-wr2      zfr11f-wr2
0                 273   2015-05-07 17:45:27.0   zja68f-wr2      zfr11f-wr2
0                 273   2015-05-07 17:50:15.0   zja68f-wr2      zfr11f-wr2

0                 273   2015-05-07 18:00:19.0   zja68f-wr2      zfr11f-wr2
0                 273   2015-05-07 18:05:18.0   zja68f-wr2      zfr11f-wr2
0                 273   2015-05-07 18:10:15.0   zja68f-wr2      zfr11f-wr2
0                 273   2015-05-07 18:15:12.0   zja68f-wr2      zfr11f-wr2
0                 273   2015-05-07 18:20:13.0   zja68f-wr2      zfr11f-wr2
0                 273   2015-05-07 18:25:14.0   zja68f-wr2      zfr11f-wr2

此结果导致2015-05-07 17:55:xx.x缺少行。可以为任何缺失的行动态添加吗?为PACKET_LOSS和PING_AVG列添加空值。

1 个答案:

答案 0 :(得分:0)

您可能想要考虑我的相当艰巨的解决方案是否值得复杂化。但是,通过使用连接"技巧"在Oracle中,我们可以通过以5分钟的间隔递增来动态创建时间表来模拟此行为。然后将它连接到router_ping表并注意我之前和之后的行,以确定我是否在路由器ping序列的中间"并酌情显示数据。 (注意:我必须更改你的where子句,因为我没有根据你的输出得到任何数据。)

select ping_date, packet_loss, ping_avg, coalesce(ping_source, previous_ping_source), coalesce(ping_destination, previous_ping_destination)
from
(
select coalesce(ping_date, ping_interval) as ping_date, 
coalesce(pings.packet_loss, dates.packet_loss) as packet_loss,
coalesce(pings.ping_avg, dates.ping_avg) as ping_avg,
pings.ping_source, 
pings.ping_destination,
coalesce(pings.ping_source, lag(pings.ping_source, 1, 0) over (order by ping_interval ASC)) previous_ping_source,
coalesce(pings.ping_destination, lag(pings.ping_destination, 1, 0) over (order by ping_interval ASC)) previous_ping_destination,
coalesce(pings.ping_source, lead(pings.ping_source, 1, 0) over (order by ping_interval ASC)) next_ping_source
from
(select ping_date,packet_loss,ping_avg,ping_source,ping_destination
from router_ping 
where ping_date > sysdate - NUMTODSINTERVAL (48, 'HOUR') AND (ping_source = 'zfr11f-wr2' AND ping_destination = 'zja68f-wr2'  OR ping_source = 'zja68f-wr2' AND ping_destination = 'zja68f-wr2' )
) pings
right outer join
(select (select min(ping_date) from router_ping) + (interval '5' minute) * level as ping_interval,
0 as packet_loss, 0 as ping_avg, 'NO DATA ROW' as data_indicator
from dual
connect by level <= 20) dates
on (pings.ping_date = dates.ping_interval))
where (previous_ping_source is not null and next_ping_source is not null)
order by ping_date
; 

示例数据和表例如:

create table router_ping
(ping_date timestamp,
ping_destination varchar2(50),
ping_source varchar2(50),
ping_avg    number,
packet_loss number);

insert into router_ping 
(ping_date, ping_destination, ping_source, ping_avg, packet_loss)
values
(to_date('2015-05-08 17:40:16','YYYY-MM-DD HH24:MI:SS'), 'zja68f-wr2', 'zfr11f-wr2', 273, 0);

insert into router_ping 
(ping_date, ping_destination, ping_source, ping_avg, packet_loss)
values
(to_date('2015-05-08 17:45:16','YYYY-MM-DD HH24:MI:SS'), 'zja68f-wr2', 'zfr11f-wr2', 273, 0);

insert into router_ping 
(ping_date, ping_destination, ping_source, ping_avg, packet_loss)
values
(to_date('2015-05-08 17:50:16','YYYY-MM-DD HH24:MI:SS'), 'zja68f-wr2', 'zfr11f-wr2', 273, 0);

insert into router_ping 
(ping_date, ping_destination, ping_source, ping_avg, packet_loss)
values
(to_date('2015-05-08 18:00:16','YYYY-MM-DD HH24:MI:SS'), 'zja68f-wr2', 'zfr11f-wr2', 273, 0);