使用最后一个非零值sql复制该值

时间:2017-08-28 10:07:08

标签: sql sql-server sql-server-2008

我有如下数据,数据按日期排序。

我需要在零时复制最后一个非零值。例如,8月15日的计数为零,因此计数应该显示20,因为最后的计数是20(8月15日),同样应该发生在8月16日 - 19日。现在21 - 22日的计数应为14.如果没有以前的值,则在8月14日的情况下为零。

我最后也添加了结果。

Date    Count
14-Aug-15   0
15-Aug-15   20
16-Aug-15   0
17-Aug-15   0
18-Aug-15   0
19-Aug-15   0
20-Aug-15   14
21-Aug-15   0
22-Aug-15   0
23-Aug-15   10
24-Aug-15   0
25-Aug-15   0
26-Aug-15   0
27-Aug-15   0
28-Aug-15   11
29-Aug-15   0
30-Aug-15   0
31-Aug-15   0
01-Sep-15   0
02-Sep-15   0
03-Sep-15   0
04-Sep-15   0

结果

Date    Count
14-Aug-15   0
15-Aug-15   20
16-Aug-15   20
17-Aug-15   20
18-Aug-15   20
19-Aug-15   20
20-Aug-15   14
21-Aug-15   14
22-Aug-15   14
23-Aug-15   10
24-Aug-15   10
25-Aug-15   10
26-Aug-15   10
27-Aug-15   10
28-Aug-15   11
29-Aug-15   11
30-Aug-15   11
31-Aug-15   11
01-Sep-15   11
02-Sep-15   11
03-Sep-15   11
04-Sep-15   11

3 个答案:

答案 0 :(得分:0)

您可以使用变量来实现它

CREATE TABLE tab
(
  n VARCHAR(10),
  d DATE,
  c INT
);


INSERT INTO tab VALUES ('A', '14-Aug-15', 0);
INSERT INTO tab VALUES ('B', '15-Aug-15', 20);
INSERT INTO tab VALUES ('C', '16-Aug-15', 0);
INSERT INTO tab VALUES ('A', '17-Aug-15', 0);
INSERT INTO tab VALUES ('B', '18-Aug-15', 0);
INSERT INTO tab VALUES ('C', '19-Aug-15', 0);
INSERT INTO tab VALUES ('D', '20-Aug-15', 14);
INSERT INTO tab VALUES ('A', '21-Aug-15', 0);

-- for each n value perform the following update
DECLARE @last INT=0;
UPDATE tab 
SET @last=c=CASE WHEN c=0 THEN @last ELSE c END
WHERE n = 'B';

答案 1 :(得分:0)

一个简单的子查询可以根据需要获得结果集(使用最后一个当前或以前的非零值)。

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>

更新值非常相似:

select [Date], 
       isnull((select top 1 [Previous].[Count] 
               from [Table] as [Previous]
               where [Previous].[Count] <> 0 and 
                     [Previous].[Date] <= [Table].[Date] and
                     [Previous].[Id] = [Table].[Id]
               order by [Previous].[Date] desc),
              0) as [Count]
from [Table]

答案 2 :(得分:0)

我认为下面的代码应该适合你 -

Create table #Source  (
id  char(1) ,
date smalldatetime,
value tinyint)
go

insert into  #Source 
 select 'A' ,'14-Aug-15' ,  0
union all  select 'B' , '15-Aug-15' ,  20
union all  select 'B'  , '16-Aug-15'  , 0
union all  select 'B'  , '17-Aug-15'  , 0
union all  select 'B'  , '18-Aug-15'  , 0
union all  select 'A' , '19-Aug-15'  , 0
union all  select 'A' , '20-Aug-15'  , 14
union all  select 'A' , '21-Aug-15'  , 0
union all  select 'B' , '22-Aug-15'  , 0
union all  select 'B', '23-Aug-15'  , 10
union all  select 'B' , '24-Aug-15'  , 0
union all  select 'B' , '25-Aug-15'  , 0
union all  select 'B' , '26-Aug-15'  , 0
union all  select 'C' , '27-Aug-15'  , 0
union all  select 'C' , '28-Aug-15'  , 11
union all  select 'C' , '29-Aug-15'  , 0
union all  select 'C' , '30-Aug-15'  , 0
union all  select 'C' , '31-Aug-15'  , 0
union all  select 'C' , '01-Sep-15'  , 0
union all  select 'B' , '02-Sep-15'  , 0
union all  select 'B' , '03-Sep-15'  , 0
union all  select 'A' , '04-Sep-15'  , 0



select t1.* , t2.value  New_value  ,  RANK() over ( partition by t1.date  
order by  t2.date desc    )  as RANK
into #dest
from #Source t1
left join #Source t2 on t1.id = t2.id and  t1.date >= t2.date  
and  t1.value=0 and t2.value <>0
order by 2

update s
set s.Value =  d.New_value  
from  #Source s join #dest d
on s.id = d.id 
and s.date = d.date 
and d.RANK = 1 and  d.New_value   is not null