0


【Sql Server】通过Sql语句批量处理数据,使用变量且遍历数据进行逻辑处理

欢迎来到《小5讲堂》,大家好,我是全栈小5。
这是《Sql Server》系列文章,每篇文章将以博主理解的角度展开讲解,
特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。
温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!

在这里插入图片描述

目录

前言

最近在进行历史数据处理,刚开始是想着通过在后端写个逻辑处理,也非常简单。
对于数据库而言,通过sql语句处理就是最好的,方便下次再处理时有个sql语句参考,
或者也方便运维人员直接使用,后端代码逻辑处理运维人员并不一定都懂。
因此,本篇文章将模拟批量数据进行sql语句遍历处理。

创建表

创建一张学生城市表,主要字段如下

-- 创建学生城市表createtable student_table
(
    id intidentity(1,1),
    name_value nvarchar(50),
    city_value nvarchar(50),
    city_value_temp nvarchar(50),
    create_time datetimedefault getdate())

模拟数据

模拟添加10条记录数据,且设置几条重复记录

-- 模拟10条记录insertinto student_table(name_value,city_value)values('张三','广州'),('张三','广州'),('张三','广州'),('李四','深圳'),('李四','深圳'),('王五','佛山'),('刘六','佛山'),('刘六','佛山'),('张七','东莞'),('吴八','惠州')

在这里插入图片描述

分组查询

按学生和城市分组查询,且having筛选有重复记录的数据

-- 学生和城市分组查询 - 有重复记录的数据select name_value,city_value,count(1) repeatcount,max(id) maxid
from student_table 
groupby name_value,city_value havingcount(1)>1

在这里插入图片描述

while实现

进行两次while遍历,然后将学生重复的城市值,除了编号最大那条记录外,其他重复记录则加序号值并赋值到city_value_temp字段里
在这里插入图片描述
1)定义变量表 - 保存重复的学生记录
2)定量变量
3)将源表中的数据插入到表变量中
4)第一层遍历
5)第一层,每次都获取第一条记录
6)定义变量表 - 保存当前学生重复记录
7)第二层遍历
8)第二层,每次都获取第一条记录
9)将当前第二层遍历记录移除
10)更新表字段
11)将当前第一层遍历记录移除

-- =====遍历处理重复数据 - 编写处理逻辑=====-- 定义变量表 - 保存重复的学生记录declare@temp_one_tabletable(
    name_value nvarchar(50),
    city_value nvarchar(50),
    repeatcount int,
    maxid int)-- 定量变量declare@maxidintdeclare@name_valuevarchar(50)declare@city_valuevarchar(50)-- 将源表中的数据插入到表变量中insertinto@temp_one_table(name_value,city_value,repeatcount,maxid)select name_value,city_value,count(1) repeatcount,max(id) maxid
from student_table 
groupby name_value,city_value havingcount(1)>1-- 第一层遍历whileexists(select city_value from@temp_one_table)begin-- 每次都获取第一条记录selecttop1@maxid=maxid,@name_value=name_value,@city_value=city_value from@temp_one_table--print(@name_value)-- 定义变量表 - 保存当前学生重复记录declare@temp_two_tabletable(
        id int,
        name_value nvarchar(50),
        city_value nvarchar(50),
        create_time datetime)insertinto@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_valueand city_value=@city_value-- 第二层遍历declare@idintwhileexists(select id from@temp_two_table)begin-- 第二层,每次都获取第一条记录selecttop1@id=id from@temp_two_tableprint(@name_value+convert(varchar,@id))-- 将当前第二层遍历记录移除deletefrom@temp_two_tablewhere id=@id-- 更新表字段if@id!=@maxidbeginupdate student_table set city_value_temp=(@city_value+convert(varchar,@id))where id=@idendend-- 将当前第一层遍历记录移除deletefrom@temp_one_tablewhere name_value=@name_valueand city_value=@city_valueendselect*from student_table
-- =====/遍历处理重复数据 - 编写处理逻辑=====

游标实现

输出编号

下面举例通过游标遍历,逐行输出编号值
在这里插入图片描述

-- 定义变量declare@idint-- 定义游标并赋值declare cursor_name cursorforselect id from student_table

-- 打开游标open cursor_name

-- 逐行获取数据fetchnextfrom cursor_name into@idwhile @@fetch_status=0beginprint(@id)-- 下一条记录fetchnextfrom cursor_name into@idend

结合临时表

在这里插入图片描述
1)定义变量
2)定义游标并赋值
3)打开游标
4)逐行获取数据
5)创建局部临时表
6)第二层遍历
7)将当前第二层遍历记录移除
8)更新表字段
9)下一条记录
10)关闭游标
11)释放游标

-- 定义变量declare@name_value nvarchar(50)declare@city_value nvarchar(50)declare@repeatcountintdeclare@maxidint-- 定义游标并赋值declare cursor_name cursorforselect name_value,city_value,count(1) repeatcount,max(id) maxid
from student_table 
groupby name_value,city_value havingcount(1)>1-- 打开游标open cursor_name

-- 逐行获取数据fetchnextfrom cursor_name into@name_value,@city_value,@repeatcount,@maxidwhile @@fetch_status=0begin--print(@name_value)-- 创建局部临时表并赋值droptable#temp_tablecreatetable#temp_table(
        id int,
        name_value nvarchar(50),
        city_value nvarchar(50),
        create_time datetime)insertinto#temp_table(id,name_value,city_value,create_time)select id,name_value,city_value,create_time from student_table 
    where name_value=@name_valueand city_value=@city_value-- 第二层遍历declare@idintwhileexists(select id from#temp_table) beginselecttop1@id=id from#temp_tableprint(@name_value+convert(varchar,@id))-- 将当前第二层遍历记录移除deletefrom#temp_table where id=@id-- 更新表字段if@id!=@maxidbeginupdate student_table set city_value_temp=(@city_value+convert(varchar,@id)),remark='游标加临时表处理'where id=@idendend-- 下一条记录fetchnextfrom cursor_name into@name_value,@city_value,@repeatcount,@maxidend-- 关闭游标close cursor_name
-- 释放游标deallocate cursor_name
select*from student_table

知识点

在 SQL Server 中,游标和临时表都是用于处理数据的工具,但它们的使用方式和目的略有不同。

游标(Cursor):

游标是一种用于逐行处理数据的数据库对象。通常在需要逐行访问数据并执行复杂操作时使用。游标可以使用以下步骤创建和操作:

  • 声明游标:定义一个游标并指定查询的结果集。
  • 打开游标:执行查询并将结果集放入游标中。
  • 逐行获取数据:使用 FETCH 语句一次从游标中获取一行数据。
  • 处理数据:对获取的数据进行操作。
  • 关闭游标:处理完数据后关闭游标,释放资源。 示例:
DECLARE@idINTDECLARE cursor_name CURSORFORSELECT id FROM table_name

OPEN cursor_name
FETCHNEXTFROM cursor_name INTO@idWHILE @@FETCH_STATUS=0BEGIN-- Process dataFETCHNEXTFROM cursor_name INTO@idENDCLOSE cursor_name
DEALLOCATE cursor_name

临时表(Temporary Table):

临时表是一种临时存储数据的表,它们一般用于在当前会话中临时存储和处理数据。SQL Server 提供了两种类型的临时表:全局临时表和局部临时表。

  • 局部临时表:以 # 开头,在当前会话中可见,在会话结束时自动删除。
  • 全局临时表:以 ## 开头,对所有会话可见,当创建它的会话结束时自动删除。 示例:
-- 创建局部临时表CREATETABLE#temp_table (
    id INT,
    name VARCHAR(50))-- 插入数据INSERTINTO#temp_table VALUES (1, 'Alice'), (2, 'Bob')-- 查询数据SELECT*FROM#temp_table-- 删除临时表(在会话结束时会自动删除)DROPTABLE#temp_table

游标用于逐行处理数据,适用于复杂逐行操作;而临时表用于临时存储和处理数据,适用于需要临时保存中间结果的情况。
在实际应用中,要根据具体需求选择合适的工具来处理数据。

文章推荐

【Sql Server】通过Sql语句批量处理数据,使用变量且遍历数据进行逻辑处理

【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据

【新星计划回顾】第四篇学习计划-自定义函数、存储过程、随机值知识点

【Sql Server】Update中的From语句,以及常见更新操作方式

【Sql server】假设有三个字段a,b,c 以a和b分组,如何查询a和b唯一,但是c不同的记录

【Sql Server】新手一分钟看懂在已有表基础上修改字段默认值和数据类型

总结:温故而知新,不同阶段重温知识点,会有不一样的认识和理解,博主将巩固一遍知识点,并以实践方式和大家分享,若能有所帮助和收获,这将是博主最大的创作动力和荣幸。也期待认识更多优秀新老博主。


本文转载自: https://blog.csdn.net/lmy_520/article/details/136648637
版权归原作者 全栈小5 所有, 如有侵权,请联系我们删除。

“【Sql Server】通过Sql语句批量处理数据,使用变量且遍历数据进行逻辑处理”的评论:

还没有评论