sql2012新的系統函數&分析函數


一 、系統函數

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 '

 

 

select mes_cEachPoRoomDF
, FORMAT(mes_cEachPoRoomDF, 'G', 'en-us')as 'Currency Format',FORMAT(mes_cEachPoRoomDF, 'C', 'en-us') as 'Currency Format'
 ,FORMAT(mes_cEachPoRoomDF, 'G', 'de-de') as 'Currency Format',FORMAT(mes_cEachPoRoomDF, 'C', 'en-us')as 'Currency Format'
 from MonthEmployCost_mes

 

 

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 (  @date31 )  AS  ' Next Month '; -- 2016-03-31
SELECT EOMONTH (  @date3- 1 )  AS  ' Last Month '; -- 2016-01-31

 

 以下新函數總體使用不多,簡單介紹

-- 語法
DATEFROMPARTS (  yearmonthday )
DATETIMEFROMPARTS (  yearmonthday, hour, minute, seconds, milliseconds )
DATETIME2FROMPARTS (  yearmonthday, hour, minute, seconds, fractions,  precision )
DATETIMEOFFSETFROMPARTS (  yearmonthday, hour, minute, seconds, fractions, hour_offset, minute_offset,  precision )
TIMEFROMPARTS ( hour, minute, seconds, fractions,  precision )

 

SELECT DATEFROMPARTS (  20101231 )  AS Result;
SELECT DATETIMEFROMPARTS (  201012312359590 )  AS Result;
SELECT DATETIME2FROMPARTS (  2010123123595900 )  AS Result;
SELECT DATETIMEOFFSETFROMPARTS (  2010123114232301207 )  AS Result;
SELECT TIMEFROMPARTS (  23595900 )  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 ]  descas LAST_PROJECT_CODE
from PROJECT p
inner  join CLIENT c
on p.CLIENT_ID =c.CLIENT_ID

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM