说我有下表:
+------------+-------+
| Date | Count |
+------------+-------+
| 11/25/2017 | 1 |
| 11/21/2017 | 1 |
| 11/20/2017 | 1 |
| 11/18/2017 | 1 |
| 11/10/2017 | 1 |
| 11/2/2017 | 0 |
| 10/27/2017 | 0 |
| 10/26/2017 | 1 |
| 10/21/2017 | 1 |
| 10/21/2017 | 1 |
| 10/17/2017 | 1 |
| 10/9/2017 | 0 |
| 10/2/2017 | 0 |
| 9/22/2017 | 0 |
| 9/14/2017 | 1 |
| 9/10/2017 | 1 |
| 9/10/2017 | 1 |
| 9/10/2017 | 0 |
| 9/4/2017 | 1 |
| 8/27/2017 | 1 |
| 8/19/2017 | 0 |
| 8/14/2017 | 0 |
+------------+-------+
我需要SQL查询来输出以下内容:
+------------+-------+------+
| Date | Count | Flag |
+------------+-------+------+
| 11/25/2017 | 1 | 1 |
| 11/21/2017 | 1 | 1 |
| 11/20/2017 | 1 | 1 |
| 11/18/2017 | 1 | 1 |
| 11/10/2017 | 1 | 1 |
| 11/2/2017 | 0 | 0 |
| 10/27/2017 | 0 | 0 |
| 10/26/2017 | 1 | 2 |
| 10/21/2017 | 1 | 2 |
| 10/21/2017 | 1 | 2 |
| 10/17/2017 | 1 | 2 |
| 10/9/2017 | 0 | 0 |
| 10/2/2017 | 0 | 0 |
| 9/22/2017 | 0 | 0 |
| 9/14/2017 | 1 | 2 |
| 9/10/2017 | 1 | 2 |
| 9/10/2017 | 1 | 2 |
| 9/10/2017 | 0 | 0 |
| 9/4/2017 | 1 | 3 |
| 8/27/2017 | 1 | 3 |
| 8/19/2017 | 0 | 0 |
| 8/14/2017 | 0 | 0 |
+------------+-------+------+
需要填充Flag列。它的值可以是0,1,2,以下是条件:
1 - 计数> 0,需要从最近的日期开始,直到Count = 0和 最小上限为3连续计数> 0
2 - 计数> 0,不是从最近的日期开始,而是检查最小上限 3连续计数> 0
直到Count = 03 - 计数= 1,连续系列没有上限
0 - 当计数为0时
请帮忙
答案 0 :(得分:5)
这是一个差距和岛屿问题
select date, count,
case when count > 0 then
case when count(*) over (partition by grn, count) >= 3 then
case when max(date) over (partition by grn, count) = max_date then 1
else 2
end
else 3
end
else 0
end flag
from
(
select date, count,
row_number() over (order by date, count)-
row_number() over (partition by count order by date, count) grn,
(select max(date) from data) max_date
from data
) t
order by date desc, count desc
iOS 10: CIKernel's ROI function did not allow tiling
该解决方案基于1的连续序列的识别,这通过创建grp
列来完成。隔离连续序列后,其余部分很简单CASE
。
答案 1 :(得分:1)
以下脚本应该执行任务
declare @test table
(dt date,
ct int
)
insert into @test values
('11/25/2017' , 1 ),
('11/21/2017', 1 ),
('11/20/2017' , 1),
('11/18/2017' , 1),
('11/10/2017' , 1),
('11/2/2017' , 0),
('10/27/2017' , 0),
('10/26/2017' , 1),
('10/21/2017' , 1),
('10/21/2017' , 1),
('10/17/2017' , 1),
('10/9/2017' , 0),
('10/2/2017' , 0),
('9/22/2017' , 0),
('9/14/2017' , 1),
('9/10/2017' , 1),
('9/10/2017' , 1),
('9/10/2017' , 0),
('9/4/2017' , 1),
('8/27/2017' , 1),
('8/19/2017' , 0),
('8/14/2017' , 0)
/***********Tag a unique identifier sorted by the date column
Each row will have the unique value
************************/
Select t.*,ROW_NUMBER()over (order by dt desc)as rw ,0 as flag
into #tmp
from @test t
order by dt desc
-- Select * from #tmp
/*******Create another table to store the start and the ending of the rows where the counter has 0's
and create another level of identifer to track the position
***********/
declare @trows table (zerorows int ,position int)
insert into @trows
Select 0 , 1
union
Select t.rw,ROW_NUMBER() over (order by t.rw) + 1 from #tmp t
where t.ct = 0
--Select * from @trows
/*******
-- Do a self join to the position table and pick up the differences where there are at least 3 consecutive numbers
-- Test this query
Select prev.zerorows+1,nxt.zerorows,nxt.zerorows - (prev.zerorows+1) from @trows nxt
inner join @trows prev on prev.position = nxt.position - 1
where nxt.zerorows - (prev.zerorows+1) >= 3
*******/
/**********Set the 1st flag ****************/
update t
set t.flag = 1
from #tmp t
where
t.rw<
( Select min(nxt.zerorows) from @trows nxt
inner join @trows prev on prev.position = nxt.position - 1
where nxt.zerorows - (prev.zerorows +1) >= 3
)
/*******************Set the 2nd flag ***************/
update t
set t.flag = 2
from #tmp t
inner join
(
Select nxt.zerorows as nxt,prev.zerorows as prev from @trows nxt
inner join @trows prev on prev.position = nxt.position - 1
where nxt.zerorows - (prev.zerorows+1) >= 3
)flagged on (t.rw between flagged.prev+1 and flagged.nxt-1)
where t.flag <> 1
/**************Set the 3rd flag *******************/
update t
set t.flag = 3
from #tmp t
where t.flag = 0 and t.ct = 1
Select * from #tmp
drop table #tmp