SQL語句之語法匯總(三)


      

  重點介紹數字函數、字符串函數、日期函數、類型轉換函數cast /convert、表連接join等基礎,並詳細講述一個綜合練習,以鞏固所學到的sql知識。

  例子或代碼中用到的table,若涉及到匯總(二)的表,如有需要請查閱匯總(二)!

一. 數字函數

  1.1 代碼

--絕對值:3.1415,3.1415
select abs(3.1415);    
select abs(-3.1415); --舍入到最大整數:4,4,-3,-3 select ceiling(3.2); select ceiling(3.7); select ceiling(-3.2); select ceiling(-3.7); --舍入到最小整數:3,3,-4,-4 select floor(3.2); select floor(3.7); select floor(-3.2); select floor(-3.7); --四舍五入到“離半徑最近的數”、后面的3即保留三位小數:3.1410,3.1420,-3.1410,-3.1420 select round(3.1413,3);
select round(3.1418,3); select round(-3.1413,3); select round(-3.1418,3);

 

------------------------------------------------

  博主經營一家發飾淘寶店,都是純手工制作哦,開業沖鑽,只為信譽!需要的親們可以光顧一下!謝謝大家的支持!
店名:
  小魚尼莫手工飾品店
經營:
  發飾、頭花、發夾、耳環等(手工制作)
網店:
  http://shop117066935.taobao.com/

  ---------------------------------------------------------------------

繼續正題... 

  

 

二. 字符串函數

  2.1 代碼

select len('abcd');                --字符串長度:4
select lower('abcdEMN');            --轉小寫
select upper('abcdEMN');           --轉大寫
select ltrim('   ss   ');         --去左空格
select rtrim('   ss   ');           --去右空格
select rtrim(ltrim('   ss   '));   --去左右空格
select substring('abcdef',3,3);     --結果:cde;格式:substring(string,startIndex,length)

  2.2 分析

  substring(string,startIndex,length),startIndex為子字符串在住字符串中的起始位置,length為子字符串的最大長度

三.日期函數

  3.1代碼

--當前時間
select getdate();
--分別獲取年/月/日
select DatePart(year,getdate()),DatePart(month,getdate()),DatePart(day,getdate());
--在當前日期運算。格式:DateAdd(datePart,number,date);注:可用hh,dd,mm,yy表示hour/day/month/year select DateAdd(hour,3,getdate()); --加三小時hour select DateAdd(day,3,getdate());   --三天day select DateAdd(month,3,getdate());  --三月month select DateAdd(year,3,getdate());   --三年year --日期差值 格式:DateDiff(datePart,startDate,endDate); select DateDiff(hh,getdate(),DateAdd(dd,3,getdate()));

  3.2 分析

  參考下面的例子

1)員工入職年限表
select FName, FInDate as 入職日期,DateDiff(year,FInDate,getdate()) as 入職年限 from T_Employee;
2)入職n年的人數統計表(FInDate為入職時間)
select DateDiff(year,FInDate,getdate()) as 入職年限, count(*) as 入職人員數 from T_Employee
group by DateDiff(year,FInDate,getdate())
3)每年入職人數統計表
select DatePart(year,FInDate),count(*) from T_Employee
group by DatePart(year,FInDate)

四. 類型轉換

  4.1代碼

1) 類型轉換兩種方式:
select cast('123'as int);
select cast('2008-08-08' as datetime);
select convert(datetime,'2009-09-09');
select convert(varchar(50),123);
2)注意:
select '123'+1;                     --不好!有時會報錯
select cast('123' as int)+1;        --最好轉化為同一類型再運算
select DatePart(year,'2008-8-8')                      --不好!有時會報錯
select DatePart(year,cast('2008-8-8' as datetime))    --最好轉化為同一類型再運算

4.2分析

  注意使用cast、convert時候,需要考慮轉換前后類型是否可以匹配,如要select cast('aaa'as int)是肯定會報錯的

  在"2)"中說到的情況還是應該注意,有些時候會出現錯誤!!!

五.case語句

  5.1代碼:

--case函數:實現離散值的判斷
select FName,
(
case FLevel           --加上'判斷值'
when 1 then'普通客戶'
when 2 then'會員'
when 3 then 'VIP'
else '未知客戶關系'
end
)as 客戶類型
from T_Customer
--case函數:實現值域的判斷
select FName,FSalary,
(
case                   --不寫'判斷值'
when FSalary<2000 then '低收入'
when FSalary>=2000 and FSalary <5000 then '中收入'
else '高收入'
end
)as 收入水平
from T_Employee

  5.2 分析

  1).上面方式分別針對離散值判斷、值域判斷;繼續參考下面的小例子

  2).有一張表記錄了比賽成績,創建代碼已經給出(大家可以參考),根據該表,完成以下題目

--創建T_Scores
create table T_Scores(FName nvarchar(50) ,score nvarchar(50))
insert into T_Scores(FName,score)values('Tom',''); 
insert into T_Scores(FName,score)values('Tom','');
insert into T_Scores(FName,score)values('Lucy','');
insert into T_Scores(FName,score)values('Lucy','');
insert into T_Scores(FName,score)values('Jerry','');

  eg_1.輸出新表,如果勝為1,負為0 

select FName,
(
case score
when N'' then 1
else 0
end
)as '',
(
case score
when N'' then 1
else 0
end
)as ''
from T_Scores

  eg_2.輸出格式(統計勝負)

  FName 勝  負
  Tom  1    1
  Lucy   0    2
  Jerry 1    0

select FName,
sum(
    case score
    when N'' then 1
    else 0
    end
)as '',
sum(
    case score
    when N'' then 1
    else 0
    end
)as ''
from T_Scores
group by FName

  3).有一張表記錄了正負值(正表示收入,負表示指出),創建代碼已經給出(大家可以參考),根據該表,完成以下題目

--創建表 T_Order
create table T_Order(FNumber varchar(50) not null,FAmount int not null);
insert into T_Order (FNumber,FAmount)values('Rk1',10);
insert into T_Order (FNumber,FAmount)values('Rk2',20);
insert into T_Order (FNumber,FAmount)values('Rk3',-30);
insert into T_Order (FNumber,FAmount)values('Rk4',-10);

  統計出收支情況,字段為 單號  收入  支出

select FNumber as 單號,
(
case 
when FAmount>0 then FAmount
else 0
end
)as 收入,
(
case 
when FAmount<0 then abs(FAmount)
else 0
end
)as 支出
from T_Order

六. 表連接join...on

  6.1 代碼:

--常規定義:
select T_Orders.BillNo,T_Customers.name
from T_Orders join T_Customers on T_Orders.CustomerId=T_Customers.Id;
--可以定義如此,書寫更簡單:
select o.BillNo as 訂單號,c.Name,c.Age
from T_Orders as o join T_Customers as c on o.CustomerId=c.Id;

6.2分析

  參考下方兩個定義的表格,實現下方要求的操作。

--T_Customers表創建
create table T_Customers(
    Id int not null,
    Name nvarchar(50) collate Chinese_PRC_CI_AS null,
    Age int null
);
insert into T_Customers(Id,Name,Age)values(1,N'tom',10);
insert into T_Customers(Id,Name,Age)values(2,N'jerry',15);
insert into T_Customers(Id,Name,Age)values(3,N'john',22);
insert into T_Customers(Id,Name,Age)values(4,N'lily',18);
insert into T_Customers(Id,Name,Age)values(5,N'lucy',18);
--T_Orders表創建
create table T_Orders(
    Id int not null,
    BillNo nvarchar(50) collate Chinese_PRC_CI_AS null,
    CustomerId int null   --看做T_Customers表的外鍵(雖然實際關系並未建立)!
);
insert into T_Orders(Id,BillNo,CustomerId)values(1,N'001',1);
insert into T_Orders(Id,BillNo,CustomerId)values(2,N'002',1);
insert into T_Orders(Id,BillNo,CustomerId)values(3,N'003',3);
insert into T_Orders(Id,BillNo,CustomerId)values(4,N'004',2);
insert into T_Orders(Id,BillNo,CustomerId)values(5,N'005',2);
insert into T_Orders(Id,BillNo,CustomerId)values(6,N'006',5);
insert into T_Orders(Id,BillNo,CustomerId)values(7,N'007',4);
insert into T_Orders(Id,BillNo,CustomerId)values(8,N'008',5);

   內容示意圖

  要求及答案:

--顯示所有訂單號對應的姓名、年齡:
select o.BillNo as 訂單號,c.Name,c.Age
from T_Orders as o join T_Customers as c on o.CustomerId=c.Id;
--顯示15歲以上顧客對應的訂單號、年齡、年齡:
select o.BillNo,c.Name,c.Age
from T_Orders as o join T_Customers as c on o.CustomerId=c.Id
where c.Age>15
--顯示年齡大於‘平均年齡’的顧客的購買訂單: (涉及子查詢)
select o.BillNo,c.Name,c.Age
from T_Orders as o join T_Customers as c on o.CustomerId=c.Id
where c.Age>(select avg(Age) from T_Customers)

七.綜合練習

  創建一張表,記錄電話呼叫員的工作流水號、呼叫員編號、對方號碼、通話開始時間、通話結束時間、。

  建表、插數據等要求自己寫SQL語句來完成。

要求:

  1)輸出所有數據中通話時間最長的5條記錄。(分析:需要用到orderby/ datediff。)

--所有通話時長(第一步)
select *, DateDiff(second,StartDateTime,EndDateTime) as '通話時長'from T_Call;
--通話時間最長的5條記錄(第二步)
select top 5* from T_Call
order by DateDiff(second,StartDateTime,EndDateTime) Desc;

  2)輸出所有數據中撥打長途號碼(以0開頭)的總時長(分析:需要用到like/ datediff /sum。)

--獲取長途號碼(第一步)
select * from T_Call where TelNum like '0%';
--長途總時長:
select'長途總時長:', sum(DateDiff(second,StartDateTime,EndDateTime))
from T_Call
where TelNum like '0%';

  3)輸出本月通話時長最多的前三位呼叫員的編號(分析:datediff / DatePart / sum/order by)

****假定當前時間為'2010-7-20'
--分辨是否為當月,0為是,其他為否(第一步)
select  CallerNumber, TelNum,DateDiff(month,StartDateTime,convert(datetime,'2010-7-20')) as '當前月'
from T_Call
--取當月的數據(第二步)
select  * from T_Call
where DatePart(month,StartDateTime)=DatePart(month,'2010-7-20')
--本月通話總時長最多的前3個呼叫員的編號(第三步)
select top 3 CallerNumber from T_Call where DatePart(month,StartDateTime)=DatePart(month,'2010-7-20') group by CallerNumber order by sum(DateDiff(second,StartDateTime,EndDateTime)) Desc --按照總量排序
備注:當月判斷也可使用 where DateDiff(month,StartDateTime,convert(datetime,'2010-7-20'))=0

  4)輸出本月撥打電話次數最多的前三位呼叫員的編號。(分析:group by/count/ order by)

--每個呼叫員撥打電話次數(第一步)
select CallerNumber, count(*)from T_Call
group by CallerNumber
--當月(第二步)
select CallerNumber, count(*)from T_Call
where DateDiff(month,StartDateTime,convert(datetime,'2010-7-20'))=0 group by CallerNumber
--本月撥打次數最多的前3個呼叫員的編號(第三步)
select top 3 CallerNumber, count(*)as '撥打次數'from T_Call
where DateDiff(month,StartDateTime,convert(datetime,'2010-7-20'))=0 group by CallerNumber
order by count(*) Desc

  5)輸出所有數據的撥號流水,並且在最后一行添加總呼叫時長,即

  呼叫員編號  對方號碼     通話時長
   ...     ...     ...
   匯總  市內號碼總時長 長途號碼總時長

--通話時長(第一步)
select Id,CallerNumber,TelNum,datediff(second,StartDateTime,EndDateTime)as '通話時長(s)'
from T_Call
--長途判斷(第二步)
select (
case
when TelNum like '0%' then 0
else 1
end
)
from T_Call
--呼叫時長分析(第三步)
select N'匯總',(
case when TelNum not like '0%' then datediff(second,StartDateTime,EndDateTime)
else 0
end
) as '市話',(
case when TelNum like '0%' then datediff(second,StartDateTime,EndDateTime)
else 0
end
) as '長途'
from T_Call
--呼叫員工編號/對方號碼/通話時長 union all 通話時長(市話/長途)(第四步)
select CallerNumber,TelNum,datediff(second,StartDateTime,EndDateTime) as '通話時長'
from T_Call
union all
--呼叫時長統計
select N'匯總',
convert(varchar(50),sum(        --類型轉換,否則溢出
case 
when TelNum not like '0%' then datediff(second,StartDateTime,EndDateTime)
else 0
end
)) as '市話',sum(
case 
when TelNum like '0%' then datediff(second,StartDateTime,EndDateTime)
else 0
end
) as '長途'
from T_Call

 

店名:
  小魚尼莫手工飾品店
經營:
  發飾、頭花、發夾、耳環等(手工制作)
網店:
  http://shop117066935.taobao.com/

 



免責聲明!

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



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