歡迎來到《小5講堂》,大家好,我是全棧小5。
這是《Sql Server》系列文章,每篇文章將以博主理解的角度展開講解,
特別是針對知識點(diǎn)的概念進(jìn)行敘說,大部分文章將會對這些概念進(jìn)行實(shí)際例子驗(yàn)證,以此達(dá)到加深對知識點(diǎn)的理解和掌握。
溫馨提示:博主能力有限,理解水平有限,若有不對之處望指正!
前言
最近在進(jìn)行歷史數(shù)據(jù)處理,剛開始是想著通過在后端寫個邏輯處理,也非常簡單。
對于數(shù)據(jù)庫而言,通過sql語句處理就是最好的,方便下次再處理時有個sql語句參考,
或者也方便運(yùn)維人員直接使用,后端代碼邏輯處理運(yùn)維人員并不一定都懂。
因此,本篇文章將模擬批量數(shù)據(jù)進(jìn)行sql語句遍歷處理。
創(chuàng)建表
創(chuàng)建一張學(xué)生城市表,主要字段如下
-- 創(chuàng)建學(xué)生城市表
create table student_table
(
id int identity(1,1),
name_value nvarchar(50),
city_value nvarchar(50),
city_value_temp nvarchar(50),
create_time datetime default getdate()
)
模擬數(shù)據(jù)
模擬添加10條記錄數(shù)據(jù),且設(shè)置幾條重復(fù)記錄
-- 模擬10條記錄
insert into student_table(name_value,city_value) values
('張三','廣州'),
('張三','廣州'),
('張三','廣州'),
('李四','深圳'),
('李四','深圳'),
('王五','佛山'),
('劉六','佛山'),
('劉六','佛山'),
('張七','東莞'),
('吳八','惠州')
分組查詢
按學(xué)生和城市分組查詢,且having篩選有重復(fù)記錄的數(shù)據(jù)
-- 學(xué)生和城市分組查詢 - 有重復(fù)記錄的數(shù)據(jù)
select name_value,city_value,count(1) repeatcount,max(id) maxid
from student_table
group by name_value,city_value having count(1)>1
while實(shí)現(xiàn)
進(jìn)行兩次while遍歷,然后將學(xué)生重復(fù)的城市值,除了編號最大那條記錄外,其他重復(fù)記錄則加序號值并賦值到city_value_temp字段里
1)定義變量表 - 保存重復(fù)的學(xué)生記錄
2)定量變量
3)將源表中的數(shù)據(jù)插入到表變量中
4)第一層遍歷
5)第一層,每次都獲取第一條記錄
6)定義變量表 - 保存當(dāng)前學(xué)生重復(fù)記錄
7)第二層遍歷
8)第二層,每次都獲取第一條記錄
9)將當(dāng)前第二層遍歷記錄移除
10)更新表字段
11)將當(dāng)前第一層遍歷記錄移除
-- =====遍歷處理重復(fù)數(shù)據(jù) - 編寫處理邏輯=====
-- 定義變量表 - 保存重復(fù)的學(xué)生記錄
declare @temp_one_table table
(
name_value nvarchar(50),
city_value nvarchar(50),
repeatcount int,
maxid int
)
-- 定量變量
declare @maxid int
declare @name_value varchar(50)
declare @city_value varchar(50)
-- 將源表中的數(shù)據(jù)插入到表變量中
insert into @temp_one_table(name_value,city_value,repeatcount,maxid)
select name_value,city_value,count(1) repeatcount,max(id) maxid
from student_table
group by name_value,city_value having count(1)>1
-- 第一層遍歷
while exists(select city_value from @temp_one_table) begin
-- 每次都獲取第一條記錄
select top 1 @maxid=maxid,@name_value=name_value,@city_value=city_value from @temp_one_table
--print(@name_value)
-- 定義變量表 - 保存當(dāng)前學(xué)生重復(fù)記錄
declare @temp_two_table table
(
id int,
name_value nvarchar(50),
city_value nvarchar(50),
create_time datetime
)
insert into @temp_two_table(id,name_value,city_value,create_time)
select id,name_value,city_value,create_time from student_table
where name_value=@name_value and city_value=@city_value
-- 第二層遍歷
declare @id int
while exists(select id from @temp_two_table) begin
-- 第二層,每次都獲取第一條記錄
select top 1 @id=id from @temp_two_table
print(@name_value+convert(varchar,@id))
-- 將當(dāng)前第二層遍歷記錄移除
delete from @temp_two_table where id=@id
-- 更新表字段
if @id!=@maxid begin
update student_table set city_value_temp=(@city_value+convert(varchar,@id)) where id=@id
end
end
-- 將當(dāng)前第一層遍歷記錄移除
delete from @temp_one_table where name_value=@name_value and city_value=@city_value
end
select * from student_table
-- =====/遍歷處理重復(fù)數(shù)據(jù) - 編寫處理邏輯=====
游標(biāo)實(shí)現(xiàn)
輸出編號
下面舉例通過游標(biāo)遍歷,逐行輸出編號值
-- 定義變量
declare @id int
-- 定義游標(biāo)并賦值
declare cursor_name cursor for
select id from student_table
-- 打開游標(biāo)
open cursor_name
-- 逐行獲取數(shù)據(jù)
fetch next from cursor_name into @id
while @@fetch_status=0 begin
print(@id)
-- 下一條記錄
fetch next from cursor_name into @id
end
結(jié)合臨時表
1)定義變量
2)定義游標(biāo)并賦值
3)打開游標(biāo)
4)逐行獲取數(shù)據(jù)
5)創(chuàng)建局部臨時表
6)第二層遍歷
7)將當(dāng)前第二層遍歷記錄移除
8)更新表字段
9)下一條記錄
10)關(guān)閉游標(biāo)
11)釋放游標(biāo)
-- 定義變量
declare @name_value nvarchar(50)
declare @city_value nvarchar(50)
declare @repeatcount int
declare @maxid int
-- 定義游標(biāo)并賦值
declare cursor_name cursor for
select name_value,city_value,count(1) repeatcount,max(id) maxid
from student_table
group by name_value,city_value having count(1)>1
-- 打開游標(biāo)
open cursor_name
-- 逐行獲取數(shù)據(jù)
fetch next from cursor_name into @name_value,@city_value,@repeatcount,@maxid
while @@fetch_status=0 begin
--print(@name_value)
-- 創(chuàng)建局部臨時表并賦值
drop table #temp_table
create table #temp_table
(
id int,
name_value nvarchar(50),
city_value nvarchar(50),
create_time datetime
)
insert into #temp_table(id,name_value,city_value,create_time)
select id,name_value,city_value,create_time from student_table
where name_value=@name_value and city_value=@city_value
-- 第二層遍歷
declare @id int
while exists(select id from #temp_table) begin
select top 1 @id=id from #temp_table
print(@name_value+convert(varchar,@id))
-- 將當(dāng)前第二層遍歷記錄移除
delete from #temp_table where id=@id
-- 更新表字段
if @id!=@maxid begin
update student_table set city_value_temp=(@city_value+convert(varchar,@id)),remark='游標(biāo)加臨時表處理' where id=@id
end
end
-- 下一條記錄
fetch next from cursor_name into @name_value,@city_value,@repeatcount,@maxid
end
-- 關(guān)閉游標(biāo)
close cursor_name
-- 釋放游標(biāo)
deallocate cursor_name
select * from student_table
知識點(diǎn)
在 SQL Server 中,游標(biāo)和臨時表都是用于處理數(shù)據(jù)的工具,但它們的使用方式和目的略有不同。
游標(biāo)(Cursor):
游標(biāo)是一種用于逐行處理數(shù)據(jù)的數(shù)據(jù)庫對象。通常在需要逐行訪問數(shù)據(jù)并執(zhí)行復(fù)雜操作時使用。游標(biāo)可以使用以下步驟創(chuàng)建和操作:
- 聲明游標(biāo):定義一個游標(biāo)并指定查詢的結(jié)果集。
- 打開游標(biāo):執(zhí)行查詢并將結(jié)果集放入游標(biāo)中。
- 逐行獲取數(shù)據(jù):使用 FETCH 語句一次從游標(biāo)中獲取一行數(shù)據(jù)。
- 處理數(shù)據(jù):對獲取的數(shù)據(jù)進(jìn)行操作。
- 關(guān)閉游標(biāo):處理完數(shù)據(jù)后關(guān)閉游標(biāo),釋放資源。
示例:
DECLARE @id INT
DECLARE cursor_name CURSOR FOR
SELECT id FROM table_name
OPEN cursor_name
FETCH NEXT FROM cursor_name INTO @id
WHILE @@FETCH_STATUS = 0
BEGIN
-- Process data
FETCH NEXT FROM cursor_name INTO @id
END
CLOSE cursor_name
DEALLOCATE cursor_name
臨時表(Temporary Table):
臨時表是一種臨時存儲數(shù)據(jù)的表,它們一般用于在當(dāng)前會話中臨時存儲和處理數(shù)據(jù)。SQL Server 提供了兩種類型的臨時表:全局臨時表和局部臨時表。
- 局部臨時表:以 # 開頭,在當(dāng)前會話中可見,在會話結(jié)束時自動刪除。
- 全局臨時表:以 ## 開頭,對所有會話可見,當(dāng)創(chuàng)建它的會話結(jié)束時自動刪除。
示例:
-- 創(chuàng)建局部臨時表
CREATE TABLE #temp_table (
id INT,
name VARCHAR(50)
)
-- 插入數(shù)據(jù)
INSERT INTO #temp_table VALUES (1, 'Alice'), (2, 'Bob')
-- 查詢數(shù)據(jù)
SELECT * FROM #temp_table
-- 刪除臨時表(在會話結(jié)束時會自動刪除)
DROP TABLE #temp_table
游標(biāo)用于逐行處理數(shù)據(jù),適用于復(fù)雜逐行操作;而臨時表用于臨時存儲和處理數(shù)據(jù),適用于需要臨時保存中間結(jié)果的情況。
在實(shí)際應(yīng)用中,要根據(jù)具體需求選擇合適的工具來處理數(shù)據(jù)。
文章推薦
【Sql Server】通過Sql語句批量處理數(shù)據(jù),使用變量且遍歷數(shù)據(jù)進(jìn)行邏輯處理
【新星計劃回顧】第六篇學(xué)習(xí)計劃-通過自定義函數(shù)和存儲過程模擬MD5數(shù)據(jù)
【新星計劃回顧】第四篇學(xué)習(xí)計劃-自定義函數(shù)、存儲過程、隨機(jī)值知識點(diǎn)
【Sql Server】Update中的From語句,以及常見更新操作方式
【Sql server】假設(shè)有三個字段a,b,c 以a和b分組,如何查詢a和b唯一,但是c不同的記錄
【Sql Server】新手一分鐘看懂在已有表基礎(chǔ)上修改字段默認(rèn)值和數(shù)據(jù)類型文章來源:http://www.zghlxwxcb.cn/news/detail-840138.html
總結(jié):溫故而知新,不同階段重溫知識點(diǎn),會有不一樣的認(rèn)識和理解,博主將鞏固一遍知識點(diǎn),并以實(shí)踐方式和大家分享,若能有所幫助和收獲,這將是博主最大的創(chuàng)作動力和榮幸。也期待認(rèn)識更多優(yōu)秀新老博主。文章來源地址http://www.zghlxwxcb.cn/news/detail-840138.html
到了這里,關(guān)于【Sql Server】通過Sql語句批量處理數(shù)據(jù),使用變量且遍歷數(shù)據(jù)進(jìn)行邏輯處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!