SQL Server中Merge子句、CTE、CONCAT、FORMAT函数用法
Merge子句
把源数据合并到目标表
点击查看代码
CREATE TABLE a (keycol INT PRIMARY KEY, col1 INT NOT NULL, col2 INT NOT NULL, col3 INT NOT NULL); CREATE TABLE b (keycol INT PRIMARY KEY, col1 INT NOT NULL, col2 INT NOT NULL, col3 INT NOT NULL); INSERT INTO a VALUES (1,0,0,0),(2,0,0,0); INSERT INTO b VALUES (1,1,1,1),(3,3,3,3); INSERT INTO a VALUES (3,0,0,0),(4,0,0,0); INSERT INTO b VALUES (4,1,1,1),(5,3,3,3); SELECT * FROM dbo.a SELECT * FROM dbo.b merge a using b on a.[keycol]=b.[keycol] when matched then update set a.col1=b.col1,a.col2=b.col2,a.col3=b.col3 when not matched then insert ([keycol],col1,col2,col3) values (b.[keycol],b.col1,b.col2,b.col3) when NOT matched BY SOURCE THEN DELETE;
output用法
点击查看代码
create table test( id int identity(1,1) primary key, name varchar(50), age int, addr varchar(50), birth datetime ) DROP TABLE dbo.test insert into test(name,age) output inserted.* values('小明',20),('小张',18),('小王',18) delete from test output deleted.* where age=18 update test set name='age_18_update',birth=GETDATE() output deleted.* ,inserted.*where age=18 --总结: --deleted- 更新前的数据(update,delete) --inserted-更新后的数据(update,insert) --注意:不能在一个INSERT语句中引用DELETED,也不能在一个DELETED语句中引用INSERTED, --因为这些虚拟表在这两种情况下逻辑上是没有意义的,所以SQL Server不会去创建。
CTE表达式
点击查看代码
CREATE TABLE Products ( Product_ID int NOT NULL, Product_Name varchar (25), Price money NULL, CONSTRAINT PK_Products PRIMARY KEY NONCLUSTERED (Product_ID) ) GO INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (1, 'Widgets', 25) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (2, 'Gadgets', 50) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (3, 'Thingies', 75) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (4, 'Whoozits', 90) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (5, 'Whatzits', 5) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (6, 'Gizmos', 15) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (7, 'Widgets', 24) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (8, 'Gizmos', 36) INSERT INTO Products (Product_ID, Product_Name, Price) VALUES (9, 'Gizmos', 36) GO --示例一(基本用法): --CET 可以看做是一个临时的结果集 --使用公用表达式可以让语句更加清晰简练 WITH MyCTE(ID, Name) as ( SELECT Product_ID as ID, Product_Name as Name from Products ) select * from MyCTE --可以在一个语句中多次引用公用表表达式(CTE) ;WITH MyCTE1(ID, Name) as ( SELECT Product_ID as ID, Product_Name as Name from Products WHERE Product_ID<5 ) ,MyCTE2(ID, Name) AS ( SELECT Product_ID as ID, Product_Name as Name from Products WHERE Product_ID>5 ) SELECT * FROM MyCTE1 UNION ALL SELECT * FROM MyCTE2 --示例二(分页): with MyCTE(ID, Name, RowID) as ( select Product_ID as ID, Product_Name as Name, Row_Number() over (order by Product_ID) as RowID from Products ) select * from MyCTE where RowID between 1 and 5 --示例三(递归) DECLARE @Table TABLE (Id INT, IdParent INT); INSERT INTO @Table VALUES (1, NULL); INSERT INTO @Table VALUES (2, 1); INSERT INTO @Table VALUES (3, 1); INSERT INTO @Table VALUES (4, 2); INSERT INTO @Table VALUES (5, 3); INSERT INTO @Table VALUES (6, 3); INSERT INTO @Table VALUES (7, 3); INSERT INTO @Table VALUES (8, 4); INSERT INTO @Table VALUES (9, 5); --SELECT * FROM @Table ;WITH CTE AS ( SELECT T.Id, T.IdParent, 1 AS [Level] FROM @Table AS T WHERE T.IdParent IS NULL UNION ALL SELECT T.Id, T.IdParent, CTE.[Level] + 1 AS [Level] FROM @Table AS T JOIN CTE ON CTE.Id = T.IdParent ) SELECT * FROM CTE ORDER BY [Level] --示例四(递归查询) --如果只是想获得某一个父级下的所有子节点,那么cet 是很不错的选择! CREATE TABLE CITYINFO( ID INT NOT NULL PRIMARY KEY IDENTITY(1,1), NAME VARCHAR(100), PID INT ) GO INSERT INTO CITYINFO VALUES('四川',0) INSERT INTO CITYINFO VALUES('成都',1) INSERT INTO CITYINFO VALUES('眉山',1) INSERT INTO CITYINFO VALUES('乐山',1) INSERT INTO CITYINFO VALUES('重庆',0) INSERT INTO CITYINFO VALUES('合川',5) INSERT INTO CITYINFO VALUES('长寿',5) INSERT INTO CITYINFO VALUES('江津',5) INSERT INTO CITYINFO VALUES('尚义',3) INSERT INTO CITYINFO VALUES('悦心',3) WITH CTE AS ( SELECT * FROM CITYINFO WHERE NAME='四川' UNION ALL SELECT A.ID,A.NAME,A.PID FROM CITYINFO AS A JOIN CTE AS B ON A.PID=B.ID ) SELECT * FROM CTE
concat与format
** 注意:只能在2012以及才能用**
点击查看代码
--1、concat()函数用于将两个字符串连接起来,形成一个单一的字符串。 SELECT CONCAT ('ab','cd') SELECT 1+NULL SELECT CONCAT ('ab',null,'cd') --或者是系统函数获取当前时间后直接与字符串连接在一起。 SELECT CONCAT ('Current system datetime is',' ',CURRENT_TIMESTAMP) --2、FORMAT函数 --FORMAT(column_name,format) column_name 要格式化的字段。format 规定格式。 --时间格式化 Select FORMAT(getdate(),'yyyy-MM-dd') --数字前补0 Select FORMAT(1,'000000') -- 000001 --使用 FORMAT 函数将日期/时间和数字值格式化为识别区域设置的字符串 --https://docs.microsoft.com/zh-cn/sql/t-sql/functions/format-transact-sql?view=sql-server-ver15 DECLARE @d DATE = '11/22/2020'; SELECT FORMAT( @d, 'd', 'en-US' ) 'US English' ,FORMAT( @d, 'd', 'en-gb' ) 'Great Britain English' ,FORMAT( @d, 'd', 'de-de' ) 'German' ,FORMAT( @d, 'd', 'zh-cn' ) 'Simplified Chinese (PRC)'; SELECT FORMAT( @d, 'D', 'en-US' ) 'US English' ,FORMAT( @d, 'D', 'en-gb' ) 'Great Britain English' ,FORMAT( @d, 'D', 'de-de' ) 'German' ,FORMAT( @d, 'D', 'zh-cn' ) 'Chinese (Simplified PRC)'; DECLARE @d DATE = GETDATE(); SELECT FORMAT( @d, 'dd/MM/yyyy', 'en-US' ) AS 'Date' ,FORMAT(123456789,'###-##-####') AS 'Custom Number';
——————
———————
时间戳timestamp
点击查看代码
CREATE TABLE [tb_Ts]([TS] TIMESTAMP) INSERT INTO [tb_Ts]([TS]) VALUES(DEFAULT) INSERT INTO [tb_Ts]([TS]) VALUES(DEFAULT) INSERT INTO [tb_Ts]([TS]) VALUES(DEFAULT) INSERT INTO [tb_Ts]([TS]) VALUES(DEFAULT) GO --1)、timestamp转换为十六进制或bigint SELECT TS ,CAST(TS AS VARBINARY(8)) AS 'timestamp转十六进制' ,CONVERT(BIGINT,TS) AS 'timestamp转bigint类型' FROM tb_Ts --2)、也可以将bigint转换为timestamp类型 DECLARE @TsValue BIGINT=10001 SELECT TS ,CAST(TS AS VARBINARY(8)) AS 'timestamp转十六进制' ,CONVERT(BIGINT,TS) AS 'timestamp转bigint类型' FROM tb_Ts WHERE TS<=CONVERT(TIMESTAMP,@TsValue)
——————
——————
STUFF函数
点击查看代码
--以下示例在第一个字符串abcdef中删除从第2个位置(字符b)开始的三个字符, --然后在删除的起始位置插入第二个字符串,从而创建并返回一个字符串。 SELECT STUFF('abcdef', 2, 3, 'ijklmn'); GO DECLARE @Users TABLE(Id INT, [Name] VARCHAR(MAX)); INSERT INTO @Users VALUES(1, 'Name 1'); INSERT INTO @Users VALUES(2, 'Name 2'); INSERT INTO @Users VALUES(3, 'Name 3'); INSERT INTO @Users VALUES(4, 'Name 4'); INSERT INTO @Users VALUES(5, 'Name 5'); -- SQLServer CAST -- 转换数据类型 逗号表示分割 。 --STUFF 函数理解 -- 第一个就是字符串 FOR XML PATH('') 必须用 , --第二个参数 负数或0空字符串,指定删除 或者插入的开始位置, --第三个参数 -- 指定删除的长度,为0表示在之前的长度插入,要替换的字符串 SELECT STUFF((SELECT CAST(Id AS NVARCHAR(MAX))+',' FROM @Users WHERE Id>=3 GROUP BY Id FOR XML PATH('')), 1, 1, 2) AS ids; --sqlserver函数 剔除字符串最后一个字符 DECLARE @str VARCHAR(MAX) SET @str='2,4,5,' SELECT LEFT(@STR,LEN(@STR)-1)
GROUP_CONCAT
合并多行为一行
点击查看代码
CREATE TABLE #YourTable ([ID] INT, [Name] CHAR(1), [Value] INT) INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'A',4) INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'B',8) INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (2,'C',9) --方法一,采用stuff函数 SELECT [ID], STUFF(( SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX)) FROM #YourTable WHERE (ID = Results.ID) FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)') ,1,2,'') AS NameValues FROM #YourTable Results GROUP BY ID --方法二:GROUP_CONCAT函数 SELECT id, dbo.GROUP_CONCAT(Name + ':' + CAST([Value] AS VARCHAR(MAX))) AS NameValues FROM #YourTable GROUP BY id; DROP TABLE #YourTable
本文来自博客园,作者:Raymon撸码记,转载请注明原文链接:https://www.cnblogs.com/RaymonGoGo/p/16667569.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?