SQL語句之語法匯總(二)


 

      繼前一篇介紹SQL的簡單語法后,本片將主要介紹實際應用中常用的語法,如數據排序order by、通配符Like過濾、空值處理、數據分組group by、限制結果集行數top 5*、子查詢、去掉數據重復distinct、聯合結果集union/union all、數字函數、字符串函數、日期函數、類型轉換函數cast /convert、索引、表連接join等,其中會結合具體代碼及例子予以說明。(考慮文章長度,部分內容將放大匯總三)

  為方便查看示例select語句,文章最后會附上需要創建的table表:  

一.數據分組group by(聚合函數)

  1.1代碼:

1.group by簡單語句
--統計每個年齡段的人數
1). select FAge,count(*)as 人數 from T_Employee group by FAge;   --right
2). select FAge,FSalary,count(*) from T_Employee group by FAge;   --error
--程序報錯:選擇列表中的列 'T_Employee.FSalary' 無效,因為該列沒有包含在聚合函數或 GROUP BY 子句中。
--分析:按照age分組,同一個age可能有好幾個工資水平,計算機無法確定顯示哪個而報錯!
3). select FAge,max(FSalary)as 最高工資,count(*) as 人數 from T_Employee group by FAge; --right!
--分析:顯示出age每組的最高工資即可
2.group by與where、having1). select FAge,count(*) from T_Employee where count(*)>1 group by FAge;--error:  
2). select FAge,count(*) from T_Employee group by FAge having count(*)>1   --right:

 

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

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

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

繼續正題... 

  

 

 1.2分析:

  1)group by是按照某一個字段來對table中信息進行整合分組,在代碼"group by簡單語句"中,1、3正確,而2錯誤,可以做如下分析:

  我們以FAge進行分組,即將每個年齡段的信息進行整合,獲取到的結果可能是23歲的有abc三個人,工資為100、200、300,那么只能取其中某一個工資水平顯示,如

max(FSalary),而不能直接寫FSalary,否則計算機必然無法確定顯示哪個而報錯!參考下圖,為“3)”的顯示結果:

  2)聚合語句不能出現在 WHERE 子句中,除非有having ,因而語句"1)"錯誤,而語句"2)"出現having,正確,分析:having對獲取到的每組信息,再進行過濾,取得人數超過1的組(結果顯示:25歲 3人等)
  3)既然存在上述情況,那是不是having可以取代where語句呢?答案是否定的,參考代碼:
a). select FAge, count(*) from T_Employee where FSalary>2000 group by FAge;   --right
b). select FAge, count(*) from T_Employee group by FAge having FSalary>2000;  --error:  
c). select FAge, count(*) from T_Employee group by FAge having FAge>25;       --right
  分析:"a)"中使用where,可以實現對分組前的數據進行過濾;即如果25歲組中有3人(3000,2000,4000),那么使用where語句后,結果為25 2人。
  而having只能對獲得的組信息進行過濾,即對"select FAge, count(*) from T_Employee group by FAge"的結果進行過濾,此時無法再對FSalary去篩選,無法實現where實現的功能,因而"b)"錯誤;
  但如果對年齡刷選having FAge>25就正確,因為select結果中包含FAge字段,可以進行簡單where對年齡的篩選,即"c)"正確!  

二.數據排序

  2.1代碼:  

1). 單字段排序:
select * from T_Employee order by FAge ASC;         --對年齡進行排序
2). 多字段排序
select * from T_Employee order by FAge ASC ,Fsalary ASC; --進一步排序(年齡相同的,按照工資排序)!前面的優先級高!
3). 對過濾后結果進行排序:
select * from T_Employee where FAge>24 order by FAge DESC;

  2.2 分析

  1)排序條件可以有多個,但越前優先級越高;

  2)ASC升序(default)、 DESC降序,平時使用排序時,ASC方式雖為默認,但最好不要省略,增強代碼可讀性

三.通配符

   3.1代碼

1). 通配符_,單個字符:
select * from T_Employee where FName LIKE '_erry';
2). 通配符%,零或多個字符:
select * from T_Employee where FName like '%n%';      --FName中含有字母n的
select * from T_Employee where FNumber like 'DEV%';   --FNumber中以DEV開始的

  3.2分析

  注意區分Like中 單字符  不定字符用法的區別!

四. 空值處理

  4.1代碼:

1)空值查詢
select 'abc'+'123'     --結果:abc123
select ''+'123'        --結果:123
select null+'123'      --結果:NULL
select * from T_Employee where FName=null;        --error  沒有結果,可以嘗試<null  >null <>null均無結果!
select * from T_Employee where FName is null;     --right  查詢到name為null的結果!
select * from T_Employee where FName is not null; --error  查詢到所有name不為null的結果! 
2)空值的處理
update T_Employee set FSubCompany=null,FDepartment='Sales'where FNumber='SALE004';  --設定某項為null
select isnull(FSubCompany,'未知子公司') from T_Employee                   --字段為null的則顯示默認值'未知子公司'
4.2分析:
  1)數據庫中,一個列如果沒有指定值,那么值就是null,此處的null與c#中的null不同,數據庫中表示“不知道”,而不是“沒有”
  2)可以嘗試FName!=null、FName=<null、FName=>null、FName=<>null均無結果!
五.限制結果集的行數

  5.1 代碼:

1). select top 5* from T_Employee                --顯示表中前五個
2). select top 5* from T_Employee order by FSalary Desc  --按照工資倒序排列,取前五個(最高的五個) 

  5.2 分析

  top 5* 表示表中前五條信息,由升序或降序來決定順序。

  top 5 FSarray表示工資的前五個,由升序或降序來決定順序。

六.子查詢

  6.1代碼: 

select top 5* from T_Employee
where FNumber not in (select top 5 FNumber from T_Employee order by FSalary Desc)
order by FSalary Desc;

  6.2 分析

  select語句嵌套,實現子查詢,即在"select得到的表"中進行二次查詢! 

 select top 5 FNumber from T_Employee order by FSalary Desc得到前五個數字;在此條件再用where查詢!
七. 去掉數據重復distinct
  7.1代碼
1). select FDepartment from T_Employee;                    --會有重復,完全顯示查詢結果
2). select distinct FDepartment from T_Employee;       --沒有重復
3).
select FDepartment,FSubCompany from T_Employee;        --會有重復,完全顯示查詢結果
4).
select distinct FDepartment,FSubCompany from T_Employee;   --僅消除完全重復的行!

  7.2 分析

  參考,當table為下表時  

  

執行"1)",完全顯示出table的所有FDepartment 內容,字段會有重復,如紅線標注區域;
執行"2)",顯示FDepartment所有分類,沒有重復 
執行"3)",完全顯示出table的所有FDepartment,FSubCompany 內容,會有重復,完全顯示查詢結果
執行"4)",僅消除完全重復的行。當FDepartment,FSubCompany數據完全相同時,數據合並,如的二個紅色框中,會合並成一條數據,而第一個框中數據有差異不會合並,

八. union與union all
  8.1代碼:
1). union會將重復數據合並9+6->14條!"表1中5條數據"+"表2中6條數據",結果可能小於11,因為將重復的FName字段合並
select FName from TempEmployee  !
union
select FName from T_Employee;
2). union all不考慮重復數據,完全合並5+6->11條!!
select FName from TempEmployee  
union all
select FName from T_Employee;
3).其他關於union的示例(只要對應字段類型一致(不嚴謹)即可)
select FName,FAge from TempEmployee
union
select FName,FAge from T_Employee;

select FName,FAge ,0 from TempEmployee
union
select FName,FAge ,1 from T_Employee;

select FName,FAge ,FIdCardNumber from TempEmployee
union
select FName,FAge,FsubCompany from T_Employee;
--可用字段'臨時工,無部門'補齊,實現union操作
select FIdCardNumber,FName,FAge ,'臨時工,無部門' fromTempEmployee   
union 
select FNumber,FName,FAge,FDepartment from T_Employee;
4).錯誤: 
select FName,FAge ,0 from TempEmployee --"0和FDepartment "類型不能轉換 union select FName,FAge,FDepartment from T_Employee;

  8.2分析

  1)union合並會消除重復項,而union  all不考慮重復,會將數據完全合並累加

  2) union時,需要兩個table中要union的結果集中,具有相同的列數,且列類型要相容才可以union

  3)union需要進行重復值掃描,效率比較低,所以如果不是確定要進行重復行合並,那么就使用union all

  4)例子

    a.在T_Employee中,(報表)查詢員工最低年齡、最高年齡?參考:  

select '正式員工最高年齡', max(FAge) from T_Employee
union all
select '正式員工最低年齡', min(FAge) from T_Employee
union all
select '臨時工最高年齡', max(FAge) from TempEmployee
union all
select '臨時工最低年齡', min(FAge) from TempEmployee;

    b.查詢正式工信息:工號、工資,在最后一行加上員工工資額合計,參考:

select FNumber,FSalary from T_Employee
union 
select '員工工資合計:',sum(FSalary) from T_Employee

 


 (待續...)

 

附:創建的幾個table

Table  T_Employee
--創建表

drop table T_Employee
create table T_Employee(FNumber varchar(20),FName varchar(20),FAge int,FSalary numeric(10,2),PRIMARY KEY(FNumber));
insert into T_Employee(FNumber,FName,FAge,FSalary)values('DEV001','Tom',25,8300);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('DEV002','Jerry',28,4300);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('HR001','Jane',25,5300);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('HR002','Tina',26,6000);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('IT001','Smith',23,3300);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('IT002','Tom',27,9300);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('SALE001','John',24,3300);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('SALE002','Kerry',22,5500);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('SALE003','Stone',25,4500);
insert into T_Employee(FNumber,FName,FAge,FSalary)values('SALE004','john',23,5500);


--修改表:

alter table T_Employee add FSubCompany varchar(20); --分公司
alter table T_Employee add FDepartment varchar(20); --部門
alter table T_Employee add FInDate datetime; --入職日期
update T_Employee set FInDate='2010-09-07 12:00:00', FSubCompany='Beijing',FDepartment='development'where FNumber='DEV001';
update T_Employee set FInDate='2011-09-07 12:00:00', FSubCompany='Shenzhen',FDepartment='development'where FNumber='DEV002';
update T_Employee set FInDate='2012-09-07 12:00:00', FSubCompany='Beijing',FDepartment='HumanResource'where FNumber='HR001';
update T_Employee set FInDate='2009-09-07 12:00:00', FSubCompany='Beijing',FDepartment='HumanResource'where FNumber='HR002';
update T_Employee set FInDate='2010-09-07 12:00:00', FSubCompany='Shenzhen',FDepartment='InfoTech'where FNumber='IT001';
update T_Employee set FInDate='2011-09-07 12:00:00', FSubCompany='Beijing',FDepartment='InfoTech'where FNumber='IT002';
update T_Employee set FInDate='2011-09-07 12:00:00', FSubCompany='Beijing',FDepartment='Sales'where FNumber='SALE001';
update T_Employee set FInDate='2012-09-07 12:00:00', FSubCompany='Shenzhen',FDepartment='Sales'where FNumber='SALE002';
update T_Employee set FInDate='2009-09-07 12:00:00', FSubCompany='Beijing',FDepartment='Sales'where FNumber='SALE003';
update T_Employee set FInDate='2009-09-07 12:00:00', FSubCompany='Shenzhen',FDepartment='Sales'where FNumber='SALE004';

 

--創建Table TempEmployee

create table TempEmployee(FIdCardNumber varchar(20),FName varchar(20),FAge int not null);

insert into TempEmployee(FIdCardNumber,FName,FAge)values('12345601','張',20);

insert into TempEmployee(FIdCardNumber,FName,FAge)values('12345602','Tom',24);

insert into TempEmployee(FIdCardNumber,FName,FAge)values('12345603','李',18);

insert into TempEmployee(FIdCardNumber,FName,FAge)values('12345604','孫',26);

insert into TempEmployee(FIdCardNumber,FName,FAge)values('12345605','周',30);

insert into TempEmployee(FIdCardNumber,FName,FAge)values('12345606','武',27); 

 

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

 


免責聲明!

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



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