SqlServer 2022通過(guò)臨時(shí)表和游標(biāo)遍歷方式邏輯處理獲取目標(biāo)數(shù)據(jù)
一、需求點(diǎn)描述
有如下數(shù)據(jù)集,有9條記錄,如果001前后一條記錄都不是001,那么就取001前面一條記錄以及本身001這條記錄、
如果001下一條記錄還是001,則取001最后一條記錄以及001剛開(kāi)始的前一條記錄
工作中心 | 序號(hào) | 備注 |
---|---|---|
1001 | 1 | |
1002 | 2 | 取這條記錄 |
001 | 3 | 取這條記錄 |
1004 | 4 | |
1008 | 5 | 取這條記錄 |
001 | 6 | 連續(xù)出現(xiàn)的首條前一條記錄 |
001 | 7 | |
001 | 8 | 取這條記錄 |
1009 | 9 |
1)查詢(xún)數(shù)據(jù)集
2)目標(biāo)數(shù)據(jù)集
二、臨時(shí)表
在 SQL Server 中,臨時(shí)表是一種用于存儲(chǔ)臨時(shí)數(shù)據(jù)的特殊表。
臨時(shí)表可以在查詢(xún)執(zhí)行期間被創(chuàng)建,并且只在當(dāng)前會(huì)話或連接有效。
它們對(duì)于需要存儲(chǔ)臨時(shí)數(shù)據(jù)的計(jì)算和操作非常有用。
SQL Server 提供了兩種類(lèi)型的臨時(shí)表:局部臨時(shí)表(Local Temporary Table)和全局臨時(shí)表(Global Temporary Table)。
2.1、局部臨時(shí)表(Local Temporary Table)
局部臨時(shí)表是以 #
開(kāi)頭的表名,只在創(chuàng)建它的會(huì)話中可見(jiàn)。
當(dāng)創(chuàng)建它的會(huì)話結(jié)束時(shí),該表會(huì)自動(dòng)刪除。其他會(huì)話無(wú)法訪問(wèn)這個(gè)表。
- 示例創(chuàng)建局部臨時(shí)表:
CREATE TABLE #TempTable ( ID INT, Name VARCHAR(50) );
2.2、全局臨時(shí)表(Global Temporary Table)
全局臨時(shí)表是以 ##
開(kāi)頭的表名,可以在創(chuàng)建它的服務(wù)器實(shí)例上的任何會(huì)話中可見(jiàn)。
當(dāng)所有引用該表的會(huì)話結(jié)束時(shí),該表會(huì)自動(dòng)刪除。
- 示例創(chuàng)建全局臨時(shí)表:
CREATE TABLE ##TempTable ( ID INT, Name VARCHAR(50) );
使用臨時(shí)表時(shí),可以像操作任何其他表一樣進(jìn)行數(shù)據(jù)插入、更新、刪除和查詢(xún)。
值得注意的是,臨時(shí)表的結(jié)構(gòu)(包括列定義和約束)與永久表類(lèi)似,可以創(chuàng)建索引、觸發(fā)器等對(duì)象。
然而,當(dāng)會(huì)話結(jié)束后,臨時(shí)表和與之相關(guān)的對(duì)象都會(huì)被自動(dòng)清理和刪除。
臨時(shí)表對(duì)于臨時(shí)性數(shù)據(jù)存儲(chǔ)和處理非常有用,例如在復(fù)雜的查詢(xún)和存儲(chǔ)過(guò)程中暫存中間結(jié)果或存儲(chǔ)需要跨多個(gè)查詢(xún)或操作之間共享的臨時(shí)數(shù)據(jù)。
三、游標(biāo)
在 SQL Server 中,游標(biāo)(Cursor)是一種用于遍歷結(jié)果集的數(shù)據(jù)庫(kù)對(duì)象。
它提供了一種逐行處理查詢(xún)結(jié)果的機(jī)制,可以在需要逐行操作數(shù)據(jù)的情況下使用。
以下是使用游標(biāo)的一般步驟:
3.1、聲明游標(biāo)
使用 DECLARE CURSOR
語(yǔ)句聲明游標(biāo),并指定游標(biāo)的名稱(chēng)和要遍歷的查詢(xún)。
DECLARE CursorName CURSOR FOR SELECT Column1, Column2 FROM TableName;
3.2、打開(kāi)游標(biāo)
使用 OPEN
語(yǔ)句打開(kāi)游標(biāo),準(zhǔn)備開(kāi)始遍歷結(jié)果集。
OPEN CursorName;
3.3、獲取數(shù)據(jù)
使用 FETCH NEXT
語(yǔ)句獲取當(dāng)前游標(biāo)位置的一行數(shù)據(jù),并將其存儲(chǔ)到變量中??梢允褂?nbsp;INTO
子句將數(shù)據(jù)存儲(chǔ)到多個(gè)變量中。
FETCH NEXT FROM CursorName INTO @Variable1, @Variable2;
3.4、處理數(shù)據(jù)
在循環(huán)中對(duì)獲取的行數(shù)據(jù)進(jìn)行處理。這可以是對(duì)數(shù)據(jù)進(jìn)行計(jì)算、更新、刪除等操作,或者僅僅是輸出數(shù)據(jù)。
WHILE @@FETCH_STATUS = 0 BEGIN -- 處理數(shù)據(jù) -- 例如執(zhí)行一些操作或輸出數(shù)據(jù) FETCH NEXT FROM CursorName INTO @Variable1, @Variable2; END;
3.5、關(guān)閉和釋放游標(biāo)
使用 CLOSE
關(guān)閉游標(biāo),將游標(biāo)的狀態(tài)置為不可使用,但不刪除游標(biāo)。最后使用 DEALLOCATE
釋放游標(biāo),并從內(nèi)存中刪除。
CLOSE CursorName; DEALLOCATE CursorName;
注意事項(xiàng):
- 使用游標(biāo)時(shí)要考慮性能和資源占用,因?yàn)橛螛?biāo)可能導(dǎo)致性能下降,并占用大量?jī)?nèi)存。
- 在處理完成后,務(wù)必關(guān)閉和釋放游標(biāo),以釋放資源。
- 可以使用
@@FETCH_STATUS
系統(tǒng)變量來(lái)判斷是否還有更多行可供遍歷。
游標(biāo)的使用需要謹(jǐn)慎考慮,只在必要的情況下使用,盡量使用集合操作來(lái)替代游標(biāo),以提高性能。
四、解決方案
根據(jù)上面了解到的臨時(shí)表和游標(biāo),結(jié)合需求,可以做如下邏輯操作,得到目標(biāo)查詢(xún)結(jié)果
代碼如下
-- 創(chuàng)建局部臨時(shí)表 if object_id('tempdb..#myTempTable') is not null begin drop table #myTempTable end /*else begin create table #myTempTable( 工作中心 varchar(50), 序號(hào) int ) end*/ -- 臨時(shí)表不存在情況下 select * into #myTempTable from( select '1001' 工作中心,1 序號(hào) union all select '1002' 工作中心,2 序號(hào) union all select '001' 工作中心,3 序號(hào) union all select '1004' 工作中心,4 序號(hào) union all select '1008' 工作中心,5 序號(hào) union all select '001' 工作中心,6 序號(hào) union all select '001' 工作中心,7 序號(hào) union all select '001' 工作中心,8 序號(hào) union all select '1009' 工作中心,9 序號(hào) ) a -- select * from #myTempTable -- 定義變狼 declare @工作中心 varchar(50) declare @序號(hào) int declare @前一個(gè)工作中心 varchar(50) declare @前一個(gè)序號(hào) int set @前一個(gè)工作中心='#' -- 定義游標(biāo) declare cursorName cursor for select 工作中心,序號(hào) from #myTempTable -- 打開(kāi)游標(biāo) open cursorName -- 遍歷游標(biāo) fetch next from cursorName into @工作中心,@序號(hào); while @@fetch_status=0 begin -- print(@工作中心) if @前一個(gè)工作中心='#' begin set @前一個(gè)工作中心=@工作中心 set @前一個(gè)序號(hào)=@序號(hào) end else begin if @工作中心='001' begin if @前一個(gè)工作中心!='001' begin -- 輸出001上的一條記錄 print(@前一個(gè)工作中心+','+convert(varchar(50),@前一個(gè)序號(hào))) end end else begin if @前一個(gè)工作中心!=@工作中心 and @前一個(gè)工作中心='001' begin -- 輸出001最后一條 print(@前一個(gè)工作中心+','+convert(varchar(50),@前一個(gè)序號(hào))) end end set @前一個(gè)工作中心=@工作中心 set @前一個(gè)序號(hào)=@序號(hào) end -- 遍歷下一條,一定要加上這句,否則會(huì)一直循環(huán) fetch next from cursorName into @工作中心,@序號(hào); end -- 關(guān)閉和銷(xiāo)毀游標(biāo) close cursorName deallocate cursorName
效果如下
到此這篇關(guān)于SqlServer 2022通過(guò)臨時(shí)表和游標(biāo)遍歷方式邏輯處理獲取目標(biāo)數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Sql2022臨時(shí)表和游標(biāo)遍歷數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQL Server查詢(xún)條件IN中能否使用變量的示例詳解
這篇文章主要介紹了SQL Server查詢(xún)條件IN中能否使用變量,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01SQL Server計(jì)算兩個(gè)時(shí)間相差的示例代碼
在SQL Server中,處理時(shí)間數(shù)據(jù)并計(jì)算時(shí)間差值是常見(jiàn)的需求,SQL Server提供了一系列函數(shù)來(lái)幫助我們完成這些操作,本文給大家介紹了SQL Server計(jì)算兩個(gè)時(shí)間相差的方法,需要的朋友可以參考下2024-10-10SQL 導(dǎo)入導(dǎo)出Excel數(shù)據(jù)的語(yǔ)句
從Excel文件中,導(dǎo)入數(shù)據(jù)到SQL數(shù)據(jù)庫(kù)中,很簡(jiǎn)單2009-11-11sql時(shí)間格式化輸出、Convert函數(shù)應(yīng)用示例
這篇文章主要介紹了sql時(shí)間格式化輸出、Convert函數(shù)應(yīng)用,需要的朋友可以參考下2014-03-03一個(gè)SQL語(yǔ)句獲得某人參與的帖子及在該帖得分總和
一個(gè)SQL語(yǔ)句獲得某人參與的帖子及在該帖得分總和...2007-04-04SQL?Server表空間碎片化回收的實(shí)現(xiàn)
本文主要介紹了SQL?Server表空間碎片化回收的實(shí)現(xiàn),文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03SQL?Server日期時(shí)間和字符串之間的轉(zhuǎn)換方法實(shí)例
處理原始數(shù)據(jù)時(shí),您可能經(jīng)常會(huì)遇到存儲(chǔ)為文本的日期值,將這些值轉(zhuǎn)換為日期數(shù)據(jù)類(lèi)型非常重要,因?yàn)樵诜治鲞^(guò)程中日期可能更有價(jià)值,下面這篇文章主要給大家介紹了關(guān)于SQL?Server日期時(shí)間和字符串之間的轉(zhuǎn)換方法,需要的朋友可以參考下2023-06-06SQLSERVER ip地址改別名的實(shí)現(xiàn)示例
本文介紹了如何將SQLSERVER的IP地址改為別名,以方便網(wǎng)絡(luò)訪問(wèn)和管理,通過(guò)修改HOSTS文件或DNS解析,這樣不僅可以提高網(wǎng)絡(luò)連接的穩(wěn)定性和可靠性,還可以方便管理員進(jìn)行遠(yuǎn)程管理和維護(hù)2023-08-08