一 、系统函数
1.字符串类函数:不用判断类型和NULL的字符串连接CONCAT函数
SQL Server本来对字符串的连接很简单,直接使用“+”号,但是需要注意两个问题,一是必须类型都是字符串类型,如果是数字类型那么会报语法错误,所以必须把数字类型转换为字符串。二是如果其中的某个值为null,那么整个连接的结果就是一个null字符串,所以还需要判断null,所以本来只是一个连接字符串的查询就会写的很复杂:
实例1:
Concat如其名称所示,用于连接两个字符串.但比过去的增强是可以免去类型转换的烦恼而直接将多个值连接为一个String值进行返回。可以明显感觉到简洁了很多。
实例2:
select
top
5
convert(
varchar(
30),eps_id)
+
'
'
+ eps_employID
+
ISNULL(epl_employName,
'')
+
convert(
char(
10),eps_dMoveInDate,
101)
from employStay_eps
join employ_epl
on eps_employID
=epl_employID
--
--现在使用CONCAT函数,直接忽略其中的类型,忽略对NULL的检查,直接连接成一个非空的字符串:
select
top
5 CONCAT(eps_id ,
'
',eps_employID,epl_employName ,FORMAT(eps_dMoveOutDate,
'
yyyy-MM-dd
'))
from employStay_eps
join employ_epl
on eps_employID
=epl_employID
2.字符串类函数:转换成字符串时设置格式的FORMAT函数。
以前要把数字或者日期转换成字符串,可以使用CONVERT函数并带人第三个整数类型的参数指定转换的格式,不过这种方法太麻烦,整数参数不容易理解和记忆,而且也不灵活。现在的FORMAT函数相当于C#中的String.Format函数,在第二个参数中可以想要输出的格式。
Format是将指定字符串按照格式和地区进行格式化
select
top
10 eps_dMoveOutDate,FORMAT(eps_dMoveOutDate,
'
yyyy-MM-dd
')
from employStay_eps
declare
@date
Datetime
=
getdate()
select format(
@date,
'
d
',
'
en-US
'),format(
@date,
'
d
',
'
zh-CN
')
3.逻辑类函数:相当于C#中三目运算符的IIF函数 。。。。可以看作是CASE…WHEN的翻版函数
这个函数和VBA中的IIF函数相同,判断第一个参数的表达式是否为真,真则返回第二个参数,假则返回第三个参数。
有了这个函数很多时候我们可以不用再使用复杂的case when语法了。比如我们判断项目的大小以显示对应的字符串,那么老的写法是:
select p.CODE,
case
when p.SIZE
>
100
then
'
Big
'
else
'
Small
'
end
as SIZE_STRING
from PROJECT p
where SIZE
is
not
null
--
现在,我们可以简单的写成:
select p.CODE,IIF(p.SIZE
>
100,
'
Big
',
'
Small
')
as SIZE_STRING
from PROJECT p
where SIZE
is
not
null
select unp_cPrice,
case
when unp_cPrice
>
1
then
'
Big
'
else
'
Small
'
end
from UnitPrice_unp
select unp_cPrice,IIF(unp_cPrice
>
1,
'
Big
',
'
Small
')
from UnitPrice_unp
select unp_cPrice,IIF(unp_cPrice
>
1,
'
Big
', IIF(unp_cPrice
<
0.8,
'
ssmall
',
'
Small
') )
from UnitPrice_unp
4逻辑类函数:让枚举显示更方便的CHOOSE函数。。。。。可以看作是CASE…WHEN的翻版函数
--
-语法
CHOOSE (
index, val_1, val_2
[
, val_n
] )
在程序中经常使用枚举值,在数据库中使用tinyint来保存枚举值,但是在查看时却不是很容易理解枚举值的含义,必须查看代码看1对应什么,2对应什么才知道。在显示的时候如果要显示成字符串,那么就需要使用case when进行判断。现在可以使用CHOOSE函数,让枚举转换成字符串变得很简单。比如要显示项目的状态,那么我们的查询就是:
select p.CODE,CHOOSE( p.STATUS,
'
Plan
',
'
Exec
',
'
Complete
',
'
Abort
',
'
Fail
')
from PROJECT p
CHOSSE函数比case when有几个缺点,1是不支持0和负数,所以如果枚举的值是0那么就没办法显示,2是枚举值必须连续而且比较小,不能使用100、200等值,那要是用CHOOSE那得写死人了。没有default值,使用case when的时候,如果不匹配还有个else值可以显示,而使用CHOOSE后如果没有匹配的,那么就是NULL值。所以个人觉得这个函数的使用面非常
实例1:按照索引号返回结果
select eps_employID,eps_PardID,eps_UserRoomID
from employStay_eps
where eps_employID
=
'
WZ100175
'
select CHOOSE(
0,eps_employID,eps_PardID,eps_UserRoomID )
from employStay_eps
where eps_employID
=
'
WZ100175
'
select CHOOSE(
1,eps_employID,eps_PardID,eps_UserRoomID )
from employStay_eps
where eps_employID
=
'
WZ100175
'
select CHOOSE(
2,eps_employID,eps_PardID,eps_UserRoomID )
from employStay_eps
where eps_employID
=
'
WZ100175
'
select CHOOSE(
3,eps_employID,eps_PardID,eps_UserRoomID )
from employStay_eps
where eps_employID
=
'
WZ100175
'
select CHOOSE(
4,eps_employID,eps_PardID,eps_UserRoomID )
from employStay_eps
where eps_employID
=
'
WZ100175
'
实例2:
select
top
5 epl_employID,epl_employName,epl_sex
,
case epl_sex
when
1
then
'
男
'
when
'
2
'
then
'
女
'
end
from employ_epl
where epl_employID
>=
'
A100086
'
select
top
5 epl_employID,epl_employName,choose(epl_sex,
'
男
',
'
女
')
from employ_epl
where epl_employID
>=
'
A100086
'
实例3:
select cti_cContractID, cti_cEmployID,cti_dStartDate
, CHOOSE(
MONTH(cti_dStartDate),
'
Winter
',
'
Winter
',
'
Spring
',
'
Spring
',
'
Spring
',
'
Summer
',
'
Summer
',
'
Summer
',
'
Autumn
',
'
Autumn
',
'
Autumn
',
'
Winter
')
AS Quarter_Hired
from ContractInfo_cti
where cti_dStartDate
>=
'
2015-01-01 00:00:00.000
'
order
by cti_dStartDate
5日期时间类函数。
除了一个EOMONTH函数是返回给定日期的最后一天外,其他的新函数,都是把年月日作为参数传进去,返回指定数据类型的对象,相当于就是CONVERT函数的变形。总体使用不多,在此简单介绍。
--
语法
EOMONTH ( start_date
[
, month_to_add
] )
DECLARE
@date
DATETIME
=
'
12/1/2011
';
SELECT EOMONTH (
@date );
--
2011-12-31
DECLARE
@date2
VARCHAR(
255)
=
'
12/1/2011
';
SELECT EOMONTH (
@date2 );
--
2011-12-31
DECLARE
@date3
DATETIME
=
GETDATE();
SELECT EOMONTH (
@date3 )
AS
'
This Month
';
--
2016-02-29
SELECT EOMONTH (
@date3,
1 )
AS
'
Next Month
';
--
2016-03-31
SELECT EOMONTH (
@date3,
-
1 )
AS
'
Last Month
';
--
2016-01-31
以下新函数总体使用不多,简单介绍
--
语法
DATEFROMPARTS (
year,
month,
day )
DATETIMEFROMPARTS (
year,
month,
day, hour, minute, seconds, milliseconds )
DATETIME2FROMPARTS (
year,
month,
day, hour, minute, seconds, fractions,
precision )
DATETIMEOFFSETFROMPARTS (
year,
month,
day, hour, minute, seconds, fractions, hour_offset, minute_offset,
precision )
TIMEFROMPARTS ( hour, minute, seconds, fractions,
precision )
SELECT DATEFROMPARTS (
2010,
12,
31 )
AS Result;
SELECT DATETIMEFROMPARTS (
2010,
12,
31,
23,
59,
59,
0 )
AS Result;
SELECT DATETIME2FROMPARTS (
2010,
12,
31,
23,
59,
59,
0,
0 )
AS Result;
SELECT DATETIMEOFFSETFROMPARTS (
2010,
12,
31,
14,
23,
23,
0,
12,
0,
7 )
AS Result;
SELECT TIMEFROMPARTS (
23,
59,
59,
0,
0 )
AS Result;
二、OVER子句的增强和新增一些分析函数。
之前OVER子句是用于RANK,ROW_NUMBER等排名函数,现在OVER子句得到了大大的增强, 可以将OVER子句应用到聚合函数中,也增加了一些分析函数。
比如我有一个项目和客户表,一个客户对于多个项目,现在需要知道客户的信息和每个客户的最新项目Code,这个要是以前还不好实现,现在我们有了分析函数,可以使用FIRST_VALUE或者LAST_VALUE再配合OVER子句,得到我们想要的结果:
select
distinct c.
*,FIRST_VALUE(p.CODE)
over(PARTITION
BY c.CLIENT_ID
order
by p.
[
CREATED_TIME
]
desc)
as LAST_PROJECT_CODE
from PROJECT p
inner
join CLIENT c
on p.CLIENT_ID
=c.CLIENT_ID