你该知道的-SQL里的这些新语法-函数
2016-12-10 00:00
323 查看
摘要: 巧用函数的霸气作用———一个简单的函数能省去很多代码量,让功能通过很简单的sql语句就能实现。
注:以下提及的方法执行环境需要SQL server2012及以上版本
![](https://static.oschina.net/uploads/img/201612/12155854_MhfN.png)
TRY_PARSE 如果强制转换失败,则返回 Null。 TRY_PARSE 仅用于从字符串转换为日期/时间和数字类型。
注:默写情况因为你不能把字符串转换为“DATE”数据类型,所以这条“SELECT”语句就会报错。但是 T-SQL 现在支持“TRY_PARSE”函数,顾名思义就是支持我们做转换测试的。
![](https://static.oschina.net/uploads/img/201612/12155854_Jj7E.png)
TRY_PARSE 如果强制转换失败,则返回 Null。
![](https://static.oschina.net/uploads/img/201612/12155854_sdtH.png)
另外还有TRY_CONVERT 、TRY_CAST函数功能都类似。
![](https://static.oschina.net/uploads/img/201612/12155854_hjuq.png)
具体请参见: https://msdn.microsoft.com/zh-cn/library/hh213316.aspx
https://msdn.microsoft.com/zh-cn/library/hh213126.aspx
![](https://static.oschina.net/uploads/img/201612/12155854_g0MY.png)
也可以结合业务这样玩
![](https://static.oschina.net/uploads/img/201612/12155854_MBPM.png)
还可以这样玩
![](https://static.oschina.net/uploads/img/201612/12155854_ROus.png)
具体请参见:https://msdn.microsoft.com/zh-cn/library/hh213019
![](https://static.oschina.net/uploads/img/201612/12155854_USOn.png)
也可以结合业务这样玩
![](https://static.oschina.net/uploads/img/201612/12155854_KC81.png)
直接使用字符串 “+”拼接
contact可以这么玩(所有参数都隐式转换为字符串类型,这里的int 类型 11)
也可以这么玩
![](https://static.oschina.net/uploads/img/201612/12155854_k9y8.png)
具体请参见:https://msdn.microsoft.com/zh-cn/library/hh231515.aspx
![](https://static.oschina.net/uploads/img/201612/12155854_MtZ5.png)
![](https://static.oschina.net/uploads/img/201612/12155854_Q01D.png)
![](https://static.oschina.net/uploads/img/201612/12155854_gl2G.png)
具体请参见:https://technet.microsoft.com/zh-cn/library/hh213020.aspx
DateDiff(DAY,a.update_date,GETDATE())=0 得到今天的数据
LAG(arg1,arg2,arg3):
arg1是从其他行返回的表达式
arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。
arg3是在arg2表示的数目超出了分组的范围时返回的值。
概念比较模糊上例子一看就知道了
具体请参见:https://msdn.microsoft.com/zh-cn/library/hh231256.aspx
https://msdn.microsoft.com/zh-cn/library/hh213125.aspx
1、以下示例使用 LAG 函数返回特定员工前几年的销售配额差异。 请注意,因为第一行没有提供滞后值,所以将返回默认值零 (0)。
下面是结果集:
2、此查询使用 LEAD 函数返回特定员工在后续年度的销售配额差异。 请注意,因为最后一行没有提供提前值,所以将返回默认值零 (0)。
下面是结果集:
具体参见:https://msdn.microsoft.com/zh-cn/library/ff878091.aspx
http://www.cnblogs.com/CareySon/archive/2012/03/12/2391581.html
具体参见:http://www.cnblogs.com/CareySon/archive/2012/03/09/2387825.html
![](https://static.oschina.net/uploads/img/201612/12155854_ZYaR.png)
WITH RESULT SETS子句同样可以使用在存储过程中,存储过程会返回大量结果集,并且每个结果集都可以自定义各自的字段名和数据类型。
注:以下提及的方法执行环境需要SQL server2012及以上版本
NO.1 PARSE 和 TRY_PARSE
PARSE 函数的功能是把字符串值转换成指定类型,这个记得以前只在写程序的时候用,现在数据库也能用了1 SELECT PARSE('2016/12/07' AS datetime2 USING 'zh-CN' ) AS Result; 2 3 DECLARE @date1 VARCHAR(8); 4 SET @date1 = CONVERT(VARCHAR(17), GETDATE(), 22); 5 SELECT PARSE(@date1 AS DATEtime using 'en-GB');
![](https://static.oschina.net/uploads/img/201612/12155854_MhfN.png)
TRY_PARSE 如果强制转换失败,则返回 Null。 TRY_PARSE 仅用于从字符串转换为日期/时间和数字类型。
注:默写情况因为你不能把字符串转换为“DATE”数据类型,所以这条“SELECT”语句就会报错。但是 T-SQL 现在支持“TRY_PARSE”函数,顾名思义就是支持我们做转换测试的。
![](https://static.oschina.net/uploads/img/201612/12155854_Jj7E.png)
TRY_PARSE 如果强制转换失败,则返回 Null。
![](https://static.oschina.net/uploads/img/201612/12155854_sdtH.png)
另外还有TRY_CONVERT 、TRY_CAST函数功能都类似。
![](https://static.oschina.net/uploads/img/201612/12155854_hjuq.png)
具体请参见: https://msdn.microsoft.com/zh-cn/library/hh213316.aspx
https://msdn.microsoft.com/zh-cn/library/hh213126.aspx
NO.2 CHOOSE 函数
CHOOSE 函数的功能是从两个或多个值的列表中返回一个值,根据指定索引值进行判断。索引值是从“1”计起的整数,也就是该函数的第一个参数。该参数后面跟着就是值列表。![](https://static.oschina.net/uploads/img/201612/12155854_g0MY.png)
也可以结合业务这样玩
![](https://static.oschina.net/uploads/img/201612/12155854_MBPM.png)
还可以这样玩
![](https://static.oschina.net/uploads/img/201612/12155854_ROus.png)
具体请参见:https://msdn.microsoft.com/zh-cn/library/hh213019
NO.3 IIF 函数
IIF 函数支持测试表达式,基于测试结果返回特定值。“IIF”函数有三个参数:有效的布尔表达式,如果表达式为真返回的值和如果表达式为假返回的值。(你可以把“IIF”函数看作是“CASE”诧句的简写版。)![](https://static.oschina.net/uploads/img/201612/12155854_USOn.png)
也可以结合业务这样玩
![](https://static.oschina.net/uploads/img/201612/12155854_KC81.png)
NO.4 CONCAT 函数
CONCAT 采用可变数量的字符串参数,并将它们串联成单个字符串。 它需要至少两个输入值;否则将引发错误。 所有参数都隐式转换为字符串类型,然后串联在一起。 Null 值被隐式转换为空字符串。 如果所有参数都为 Null,则返回 varchar(1) 类型的空字符串。 隐式转换为字符串的过程遵循现有的数据类型转换规则。直接使用字符串 “+”拼接
---会返回NULL declare @a char(10) set @a = null select @a + 'a' ---会报错 declare @b int set @b = 1 select @b + 'a'
contact可以这么玩(所有参数都隐式转换为字符串类型,这里的int 类型 11)
SELECT CONCAT ( 'Happy ', 'Birthday ', 11, '/', '25' ) AS Result;
也可以这么玩
SELECT CONCAT(Name, ' (', ProductNumber, ')') AS NewName FROM Production.Product WHERE ProductID = 970;
![](https://static.oschina.net/uploads/img/201612/12155854_k9y8.png)
具体请参见:https://msdn.microsoft.com/zh-cn/library/hh231515.aspx
NO.5 DATEFROMPARTS、TIMEFROMPARTS、DATETIMEFROMPARTS 和 DATETIME2FROMPARTS
略去概念描述,一看就懂1 SELECT DATEFROMPARTS(2016, 12, 7); --年,月,日 2 SELECT TIMEFROMPARTS(23, 4, 18, 53, 3); --时,分,秒,秒的小数部分,精度 3 SELECT DATETIMEFROMPARTS(2016, 12, 7, 23, 4, 18, 53); --年,月,日,时,分,秒,秒的小数部分,默认3位精度 4 SELECT DATETIME2FROMPARTS(2016, 12, 7, 23, 4, 18, 53, 7); --年,月,日,时,分,秒,秒的小数部分,可指定精度
![](https://static.oschina.net/uploads/img/201612/12155854_MtZ5.png)
NO.6 EOMONTH 函数
一个有趣的函数,返回包含指定日期的月份的最后一天(具有可选偏移量)。![](https://static.oschina.net/uploads/img/201612/12155854_Q01D.png)
![](https://static.oschina.net/uploads/img/201612/12155854_gl2G.png)
具体请参见:https://technet.microsoft.com/zh-cn/library/hh213020.aspx
DateDiff(DAY,a.update_date,GETDATE())=0 得到今天的数据
NO.7 LAG 与 LEAD
访问相同结果集中先前行/后续行中的数据,而用不使用自联接。 LAG 以当前行之前的给定物理偏移量来提供对行的访问。LEAD 以当前行之后的给定物理偏移量来提供对行的访问。在 SELECT 语句中使用此分析函数可将当前行中的值与先前行/后续行中的值进行比较。LAG(arg1,arg2,arg3):
arg1是从其他行返回的表达式
arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。
arg3是在arg2表示的数目超出了分组的范围时返回的值。
概念比较模糊上例子一看就知道了
1 WITH test 2 as 3 ( 4 select NULL as score 5 UNION ALL 6 select 10 7 UNION ALL 8 select 20 9 UNION ALL 10 select 30 11 UNION ALL 12 select 40 13 UNION ALL 14 select 50 15 ) 16 select ROW_NUMBER() over(order by score) as rownum 17 ,score 18 ,LEAD(score) over(order by score) as nextscore1 19 ,LEAD(score,1) over(order by score) as nextscore2 20 ,LEAD(score,1,0) over(order by score) as nextscore3 21 ,LEAD(score,2) over(order by score) as nextscore4 22 ,LAG(score) over(order by score) as previousscore1 23 ,LAG(score,1) over(order by score) as previousscore2 24 ,LAG(score,1,0) over(order by score) as previousscore3 25 ,LAG(score,2) over(order by score) as previousscore4 26 from test
具体请参见:https://msdn.microsoft.com/zh-cn/library/hh231256.aspx
https://msdn.microsoft.com/zh-cn/library/hh213125.aspx
1、以下示例使用 LAG 函数返回特定员工前几年的销售配额差异。 请注意,因为第一行没有提供滞后值,所以将返回默认值零 (0)。
USE AdventureWorks2012; GO SELECT BusinessEntityID, YEAR(QuotaDate) AS SalesYear, SalesQuota AS CurrentQuota, LAG(SalesQuota, 1,0) OVER (ORDER BY YEAR(QuotaDate)) AS PreviousQuota FROM Sales.SalesPersonQuotaHistory WHERE BusinessEntityID = 275 and YEAR(QuotaDate) IN ('2005','2006');
下面是结果集:
BusinessEntityID SalesYear CurrentQuota PreviousQuota ---------------- ----------- --------------------- --------------------- 275 2005 367000.00 0.00 275 2005 556000.00 367000.00 275 2006 502000.00 556000.00 275 2006 550000.00 502000.00 275 2006 1429000.00 550000.00 275 2006 1324000.00 1429000.00
2、此查询使用 LEAD 函数返回特定员工在后续年度的销售配额差异。 请注意,因为最后一行没有提供提前值,所以将返回默认值零 (0)。
USE AdventureWorks2012; GO SELECT BusinessEntityID, YEAR(QuotaDate) AS SalesYear, SalesQuota AS CurrentQuota, LEAD(SalesQuota, 1,0) OVER (ORDER BY YEAR(QuotaDate)) AS NextQuota FROM Sales.SalesPersonQuotaHistory WHERE BusinessEntityID = 275 and YEAR(QuotaDate) IN ('2005','2006');
下面是结果集:
BusinessEntityID SalesYear CurrentQuota NextQuota ---------------- ----------- --------------------- --------------------- 275 2005 367000.00 556000.00 275 2005 556000.00 502000.00 275 2006 502000.00 550000.00 275 2006 550000.00 1429000.00 275 2006 1429000.00 1324000.00 275 2006 1324000.00 0.00
NO.8 序列 SEQUENCE
从 SQL Server 2012 开始,你现在可以定义序列数据库对象了。序列提供了生成一组唯一数字值的机制,可以在整个数据库范围内使用,而不是仅局限于一个表,与“IDENTITY”属性的用法有点类似。尽管你可以使用“IDENTITY”属性生成在整个数据库中可用的数字值,但那个过程有点麻烦。序列功能使得一切更容易了。具体参见:https://msdn.microsoft.com/zh-cn/library/ff878091.aspx
http://www.cnblogs.com/CareySon/archive/2012/03/12/2391581.html
NO.9 使用结果集 (2012分页方法增强)
2012分页方法增强不仅使得分页变得更容易,也在效率上有了一定的提升。具体参见:http://www.cnblogs.com/CareySon/archive/2012/03/09/2387825.html
NO.10 drop table if exists
在我们写T-SQL要删除某个对象(表、存储过程等)时,一般会习惯先用IF语句判断该对象是否存在,然后DROP,比如:create table DropIFExists(a int) --老写法 IF OBJECT_ID('dbo.DropIFExists','U') IS NOT NULL DROP TABLE DropIFExists --或 IF EXISTS (SELECT * FROM sys.objects where name = 'DropIFExists') DROP TABLE DropIFExists --SQL2016中新增 drop table if exists DropIFExists
![](https://static.oschina.net/uploads/img/201612/12155854_ZYaR.png)
NO.11 RESULT SETS
WITH RESULT SETS可以重新定义从存储过程中返回结果的字段名和数据类型。这会使得向拥有特定字段名和数据类型的临时表的结果集中插入记录将变得非常容易,并且不需要依赖存储过程返回了哪些内容。WITH RESULT SETS子句同样可以使用在存储过程中,存储过程会返回大量结果集,并且每个结果集都可以自定义各自的字段名和数据类型。
1 CREATE PROCEDURE GetPerson 2 AS 3 BEGIN 4 SELECT TOP 10 BUSINESSENTITYID,CONCAT( FirstName ,' ',MiddleName,' ' , LastName) AS Name 5 FROM [Person].[Person] 6 END 7 GO 8 EXECUTE GetPerson 9 GO 10 EXECUTE GetPerson 11 WITH RESULT SETS 12 ( 13 ( 14 PersonId INT, 15 PersonName VARCHAR(150) 16 ) 17 ) 18 GO
![](https://static.oschina.net/uploads/img/201612/12155854_8STx.png)
相关文章推荐
- 你该知道的-SQL里的这些新语法-函数
- 你该知道的-SQL里的这些新语法-函数
- 从SQL Server向Oracle迁移的技术实现方案(七)常用SQL语法与函数
- 学习SQL应知道的动态SQL语句基本语法
- SQL语法整理[6]——函数
- Oracle模糊查询之(3.1从使用函数和sql语法角度来提高模糊查询效率 一)oracle模糊查询效率提高
- SQL DATEDIFF语法及时间函数 Sql 查询当天、本周、本月记录
- 学习SQL应知道的动态SQL语句基本语法
- Hibernate之QBE--》用语法函数表示sql语句【个人感觉此技术相当之垃圾,反其正道而行】(二十八)
- SQL DATEDIFF语法及时间函数 Sql 查询当天、本周、本月记录
- SQL2005之后MS SQL版本 T-SQL 新增语法、函数(三)
- Oracle模糊查询之(3.3从使用函数和sql语法角度来提高模糊查询效率 三)使用Oracle的instr函数与索引配合提高模糊查询的效率
- 学习SQL应知道的动态SQL语句基本语法(阅读)
- 学习SQL应知道的动态SQL语句基本语法
- 学习SQL应知道的动态SQL语句基本语法
- SQL DATEDIFF语法及时间函数 Sql 查询当天、本周、本月记录
- 刚知道SQL中的CAST()函数是这样用的
- 学习SQL应知道的动态SQL语句基本语法
- 揭开AS程序的外纱(七) -- 函数的这些,你知道不?
- 【原】unity这些函数你知道吗?