利用 while 迴圈取得資料區間

本文將介紹如何利用 while 迴圈取得資料區間。

情境描述

論壇上有朋友討論到想要利用 T-SQL 從一連串資料中根據 type 資料行想要找出相同 type 最近的兩個 id(例如下列的原始資料的相同顏色所標示)。

image

期望的結果如下圖所示:

image

實作步驟

根據上述需求筆者以下列的 T-SQL 來實現,雖然解法沒有很漂亮,但還是可以硬湊出發問者所需要的結果,因此記錄下來,希望對有類似需求的朋友可以多少提供點幫助,提醒您使用時請自行依照您的環境及實際環境進行調整。

use tempdb
go

	

	
--#region 準備測試資料
declare @t1 table
(id tinyint,type char(1))

	
insert into @t1 values(1,'A')
insert into @t1 values(2,'A')
insert into @t1 values(3,'B')
insert into @t1 values(4,'B')
insert into @t1 values(5,'A')
insert into @t1 values(6,'C')
insert into @t1 values(7,'A')
insert into @t1 values(8,'C')
insert into @t1 values(9,'B')
insert into @t1 values(10,'C')
insert into @t1 values(11,'D')
insert into @t1 values(12,'C')
insert into @t1 values(13,'E')
insert into @t1 values(14,'B')

	
declare @t2 table
(type  char(1),idmin tinyint, idmax tinyint)
--#endregion

	
declare @rowcount int,@i int = 1,@type char(1),@id tinyint = 1
set @rowcount = (select count(*) from @t1)

	
--#region 以迴圈方式Loop原始資料表
while @i <= @rowcount
    begin
        
        select @type = type,@id = id
        from (
            select ROW_NUMBER() OVER (ORDER BY type,id) as sn,id,type
            from @t1
            ) t
        where t.sn = @i        
        
        if not exists (select * from @t2
                             where type = @type
                             and idmin = (select top 1 id
                                          from @t1
                                          where type = @type
                                           and id < @id
                                          order by id desc)
                             and idmax = 0)
            begin
                insert into @t2 values (@type,@id,0)
            end
        else
            begin
                update @t2
                set idmax = @id
                where type = @type
                and idmin = (select top 1 id
                             from @t1
                             where type = @type
   and id < @id
                             order by id desc)
                and idmax = 0
            end
        set @i = @i + 1
    end
--#endregion

	
--更新落單的紀錄,設定idmax等於idmin
update @t2
set idmax = idmin
where idmax = 0

	
--檢視結果
select *
from @t2
order by idmin

參考資料

- sql抓資料區間