t-sql,用最后一个值替换Null - 包含Unions

时间:2018-04-25 20:54:31

标签: sql-server tsql sql-server-2016

我有以下查询:

declare @s1_data int;
declare @s2_data int;
declare @s3_data int;
declare @s4_data int;
declare @s5_data int;
declare @s6_data int;

select  aa.t_stamp, 
        aa.Stat as S1_Stat, 
        @s2_data as S2_Stat, 
        @s3_data as S3_Stat, 
        @s4_data as S4_Stat, 
        @s5_data as S5_Stat, 
        @s6_data as S6_Stat 
from Line4283_1_rtStat aa 
where t_stamp between '{Root Container.Date Range.startDate}' 
                  and '{Root Container.Date Range.endDate}'
Union
select ab.t_stamp, @s1_data, ab.Stat ,@s3_data, @s4_data, @s5_data, @s6_data 
from Line4283_2_rtStat ab
where t_stamp between '{Root Container.Date Range.startDate}' 
                  and '{Root Container.Date Range.endDate}'
Union
select ac.t_stamp, @s1_data, @s2_data, ac.Stat, @s4_data, @s5_data, @s6_data 
from Line4283_3_rtStat ac
where t_stamp between '{Root Container.Date Range.startDate}'  
                  and '{Root Container.Date Range.endDate}'
Union
select ad.t_stamp, @s1_data, @s2_data, @s3_data, ad.Stat, @s5_data, @s6_data 
from Line4283_4_rtStat ad
where t_stamp between '{Root Container.Date Range.startDate}'  
                  and '{Root Container.Date Range.endDate}'
Union
select ae.t_stamp, @s1_data, @s2_data, @s3_data ,@s4_data, ae.Stat, @s6_data 
from Line4283_5_rtStat ae
where t_stamp between '{Root Container.Date Range.startDate}'  
                  and '{Root Container.Date Range.endDate}'
Union
select af.t_stamp, @s1_data, @s2_data, @s3_data ,@s4_data ,@s5_data, af.Stat 
from Line4283_6_rtStat af
where t_stamp between '{Root Container.Date Range.startDate}'  
                  and '{Root Container.Date Range.endDate}'
union
select '{Root Container.Date Range.endDate}', 0, 0, 0, 0, 0, 0

{Root Container.Date Range.startDate}{Root Container.Date Range.endDate}是在运行时填充的变量。

此查询有效并返回类似这样的内容,只是这是仅读取前两行数据的结果:

2018-03-29 11:00:00.000     2       NULL
2018-03-29 12:00:00.000     3       NULL
2018-03-29 13:00:00.000     4       NULL
2018-04-09 15:57:57.270     2       NULL
2018-04-09 16:01:10.193     NULL    1
2018-04-09 16:01:46.430     NULL    7
2018-04-09 16:02:09.547     NULL    1
2018-04-09 16:04:23.710     NULL    3
2018-04-09 16:04:40.850     NULL    1
2018-04-09 16:04:49.907     NULL    3
2018-04-09 16:04:52.920     NULL    1
etc'

为了完成这项工作,我想将NULL值替换为同一列中出现的最后一个值。我不确定如何使用所有这些将数据转换为可行格式所需的联合。

查询需要以当前结构化的方式返回数据,以允许我导入数据的工具正确显示数据。

精确SQL Server版本:13.0.4210.6

我最终做了以下事情。以下是我写的程序的副本:

ALTER PROCEDURE [dbo].[statusFill] 
-- Add the parameters for the stored procedure here
 @start datetime,
 @end datetime
AS
BEGIN

declare @insertDate datetime;
declare @insertDateSpan datetime;
declare @s1_stat int;
declare @s1_hold int;
declare @s2_stat int;
declare @s2_hold int;
declare @s3_stat int;
declare @s3_hold int;
declare @s4_stat int;
declare @s4_hold int;
declare @s5_stat int;
declare @s5_hold int;
declare @s6_stat int;
declare @s6_hold int;

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SET @insertDate = @start;
IF EXISTS (SELECT * FROM sysobjects WHERE name='status' AND xtype='U')
drop table #status

IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='status' AND xtype='U')
create table #status
( 
t_stamp datetime,
S1_Stat int,
S2_Stat int,
S3_Stat int,
S4_Stat int,
S5_Stat int,
S6_Stat int
)

WHILE @insertDate < @end
BEGIN
select @insertDateSpan = DATEADD(second,5,@insertDate)
if @insertDate = @start
    select @s1_stat = isnull((select top (1) stat from Line4283_1_rtStat     where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),
    (select top (1) stat from Line4283_1_rtStat where t_stamp <     @insertDate order by t_stamp asc))  
else
    select @s1_stat = isnull((select top (1) stat from Line4283_1_rtStat where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),@s1_hold)

if @s1_stat is not null
    select @s1_hold = @s1_stat;

-- station #2
if @insertDate = @start
    select @s2_stat = isnull((select top (1) stat from Line4283_2_rtStat     where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),
    (select top (1) stat from Line4283_2_rtStat where t_stamp <     @insertDate order by t_stamp asc))  
else
    select @s2_stat = isnull((select top (1) stat from Line4283_2_rtStat where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),@s2_hold)

if @s2_stat is not null
    select @s2_hold = @s2_stat;

-- station #3
if @insertDate = @start
    select @s3_stat = isnull((select top (1) stat from Line4283_3_rtStat     where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),
    (select top (1) stat from Line4283_3_rtStat where t_stamp <     @insertDate order by t_stamp asc))  
else
    select @s3_stat = isnull((select top (1) stat from Line4283_3_rtStat where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),@s3_hold)

if  @s3_stat is not null
    select @s3_hold = @s3_stat;

    -- station #4
if @insertDate = @start
    select @s4_stat = isnull((select top (1) stat from Line4283_4_rtStat where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),
    (select top (1) stat from Line4283_2_rtStat where t_stamp < @insertDate order by t_stamp asc))  
else
    select @s4_stat = isnull((select top (1) stat from Line4283_4_rtStat where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),@s4_hold)

if @s4_stat is not null
    select @s4_hold = @s4_stat;
-- station #5
if @insertDate = @start
    select @s5_stat = isnull((select top (1) stat from Line4283_5_rtStat     where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),
    (select top (1) stat from Line4283_5_rtStat where t_stamp <     @insertDate order by t_stamp asc))  
else
    select @s5_stat = isnull((select top (1) stat from Line4283_5_rtStat where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),@s5_hold)

if @s5_stat is not null
    select @s5_hold = @s5_stat;

-- station #6
if @insertDate = @start
    select @s6_stat = isnull((select top (1) stat from Line4283_6_rtStat     where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),
    (select top (1) stat from Line4283_6_rtStat where t_stamp <     @insertDate order by t_stamp asc))  
else
    select @s6_stat = isnull((select top (1) stat from Line4283_6_rtStat where t_stamp between @insertDate and @insertDateSpan order by t_stamp asc),@s6_hold)

if @s6_stat is not null
    select @s6_hold = @s6_stat;






insert into #status (t_stamp,S1_Stat,S2_Stat,S3_Stat,S4_Stat,S5_Stat,S6_Stat)
select @insertDate,@s1_stat,@s2_stat,@s3_stat,@s4_stat,@s5_stat,@s6_stat
select @insertDate =DATEADD(second,5,@insertDate)
END;


select t_stamp,S1_Stat,S2_Stat,S3_Stat,S4_Stat,S5_Stat,S6_Stat  from #status
drop table #status
END

这有点不同但它实际上在一秒钟内运行典型的执行。这允许我创建5秒窗口,并用数据填充它们或将最后的已知值粘贴在其中。

0 个答案:

没有答案