SqlServer 2022通過臨時表和游標遍歷方式邏輯處理獲取目標數(shù)據(jù)
一、需求點描述
有如下數(shù)據(jù)集,有9條記錄,如果001前后一條記錄都不是001,那么就取001前面一條記錄以及本身001這條記錄、
如果001下一條記錄還是001,則取001最后一條記錄以及001剛開始的前一條記錄
工作中心 | 序號 | 備注 |
---|---|---|
1001 | 1 | |
1002 | 2 | 取這條記錄 |
001 | 3 | 取這條記錄 |
1004 | 4 | |
1008 | 5 | 取這條記錄 |
001 | 6 | 連續(xù)出現(xiàn)的首條前一條記錄 |
001 | 7 | |
001 | 8 | 取這條記錄 |
1009 | 9 |
1)查詢數(shù)據(jù)集
2)目標數(shù)據(jù)集
二、臨時表
在 SQL Server 中,臨時表是一種用于存儲臨時數(shù)據(jù)的特殊表。
臨時表可以在查詢執(zhí)行期間被創(chuàng)建,并且只在當前會話或連接有效。
它們對于需要存儲臨時數(shù)據(jù)的計算和操作非常有用。
SQL Server 提供了兩種類型的臨時表:局部臨時表(Local Temporary Table)和全局臨時表(Global Temporary Table)。
2.1、局部臨時表(Local Temporary Table)
局部臨時表是以 #
開頭的表名,只在創(chuàng)建它的會話中可見。
當創(chuàng)建它的會話結束時,該表會自動刪除。其他會話無法訪問這個表。
- 示例創(chuàng)建局部臨時表:
CREATE TABLE #TempTable ( ID INT, Name VARCHAR(50) );
2.2、全局臨時表(Global Temporary Table)
全局臨時表是以 ##
開頭的表名,可以在創(chuàng)建它的服務器實例上的任何會話中可見。
當所有引用該表的會話結束時,該表會自動刪除。
- 示例創(chuàng)建全局臨時表:
CREATE TABLE ##TempTable ( ID INT, Name VARCHAR(50) );
使用臨時表時,可以像操作任何其他表一樣進行數(shù)據(jù)插入、更新、刪除和查詢。
值得注意的是,臨時表的結構(包括列定義和約束)與永久表類似,可以創(chuàng)建索引、觸發(fā)器等對象。
然而,當會話結束后,臨時表和與之相關的對象都會被自動清理和刪除。
臨時表對于臨時性數(shù)據(jù)存儲和處理非常有用,例如在復雜的查詢和存儲過程中暫存中間結果或存儲需要跨多個查詢或操作之間共享的臨時數(shù)據(jù)。
三、游標
在 SQL Server 中,游標(Cursor)是一種用于遍歷結果集的數(shù)據(jù)庫對象。
它提供了一種逐行處理查詢結果的機制,可以在需要逐行操作數(shù)據(jù)的情況下使用。
以下是使用游標的一般步驟:
3.1、聲明游標
使用 DECLARE CURSOR
語句聲明游標,并指定游標的名稱和要遍歷的查詢。
DECLARE CursorName CURSOR FOR SELECT Column1, Column2 FROM TableName;
3.2、打開游標
使用 OPEN
語句打開游標,準備開始遍歷結果集。
OPEN CursorName;
3.3、獲取數(shù)據(jù)
使用 FETCH NEXT
語句獲取當前游標位置的一行數(shù)據(jù),并將其存儲到變量中??梢允褂?nbsp;INTO
子句將數(shù)據(jù)存儲到多個變量中。
FETCH NEXT FROM CursorName INTO @Variable1, @Variable2;
3.4、處理數(shù)據(jù)
在循環(huán)中對獲取的行數(shù)據(jù)進行處理。這可以是對數(shù)據(jù)進行計算、更新、刪除等操作,或者僅僅是輸出數(shù)據(jù)。
WHILE @@FETCH_STATUS = 0 BEGIN -- 處理數(shù)據(jù) -- 例如執(zhí)行一些操作或輸出數(shù)據(jù) FETCH NEXT FROM CursorName INTO @Variable1, @Variable2; END;
3.5、關閉和釋放游標
使用 CLOSE
關閉游標,將游標的狀態(tài)置為不可使用,但不刪除游標。最后使用 DEALLOCATE
釋放游標,并從內(nèi)存中刪除。
CLOSE CursorName; DEALLOCATE CursorName;
注意事項:
- 使用游標時要考慮性能和資源占用,因為游標可能導致性能下降,并占用大量內(nèi)存。
- 在處理完成后,務必關閉和釋放游標,以釋放資源。
- 可以使用
@@FETCH_STATUS
系統(tǒng)變量來判斷是否還有更多行可供遍歷。
游標的使用需要謹慎考慮,只在必要的情況下使用,盡量使用集合操作來替代游標,以提高性能。
四、解決方案
根據(jù)上面了解到的臨時表和游標,結合需求,可以做如下邏輯操作,得到目標查詢結果
代碼如下
-- 創(chuàng)建局部臨時表 if object_id('tempdb..#myTempTable') is not null begin drop table #myTempTable end /*else begin create table #myTempTable( 工作中心 varchar(50), 序號 int ) end*/ -- 臨時表不存在情況下 select * into #myTempTable from( select '1001' 工作中心,1 序號 union all select '1002' 工作中心,2 序號 union all select '001' 工作中心,3 序號 union all select '1004' 工作中心,4 序號 union all select '1008' 工作中心,5 序號 union all select '001' 工作中心,6 序號 union all select '001' 工作中心,7 序號 union all select '001' 工作中心,8 序號 union all select '1009' 工作中心,9 序號 ) a -- select * from #myTempTable -- 定義變狼 declare @工作中心 varchar(50) declare @序號 int declare @前一個工作中心 varchar(50) declare @前一個序號 int set @前一個工作中心='#' -- 定義游標 declare cursorName cursor for select 工作中心,序號 from #myTempTable -- 打開游標 open cursorName -- 遍歷游標 fetch next from cursorName into @工作中心,@序號; while @@fetch_status=0 begin -- print(@工作中心) if @前一個工作中心='#' begin set @前一個工作中心=@工作中心 set @前一個序號=@序號 end else begin if @工作中心='001' begin if @前一個工作中心!='001' begin -- 輸出001上的一條記錄 print(@前一個工作中心+','+convert(varchar(50),@前一個序號)) end end else begin if @前一個工作中心!=@工作中心 and @前一個工作中心='001' begin -- 輸出001最后一條 print(@前一個工作中心+','+convert(varchar(50),@前一個序號)) end end set @前一個工作中心=@工作中心 set @前一個序號=@序號 end -- 遍歷下一條,一定要加上這句,否則會一直循環(huán) fetch next from cursorName into @工作中心,@序號; end -- 關閉和銷毀游標 close cursorName deallocate cursorName
效果如下
到此這篇關于SqlServer 2022通過臨時表和游標遍歷方式邏輯處理獲取目標數(shù)據(jù)的文章就介紹到這了,更多相關Sql2022臨時表和游標遍歷數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!