1、查詢所有列 select *from emp;--*表示所有的,from emp表示從emp表中查詢。 2、查詢指定列 select empno,ename from emp; select 888 from emp;--ok,輸出的行數是emp表的行數,每行只有一個欄位,值是888。 sele ...
1、查詢所有列
select *from emp;--*表示所有的,from emp表示從emp表中查詢。
2、查詢指定列
select empno,ename from emp;
select 888 from emp;--ok,輸出的行數是emp表的行數,每行只有一個欄位,值是888。
select 5;--OK,不推薦。
3、消除重覆元祖:distinct
select distinct deptno from emp;--distinct deptno會過濾掉重覆的deptno,也可以過濾掉null,即如果有多個null只輸出一個。
select distinct comm,deptno from emp;--把comm和deptno的組合進行過濾。
select deptno,distinct comm from emp;--error,邏輯上有衝突。
4、給屬性列取別名:as
select ename,sal*12 as "年薪" from emp;--as可以省略。
5、查詢經過計算的列
select ename,sal*12 as "年薪" from emp;--as可以省略。
lower()將大寫字母改為小寫字母;upper()將字元串轉換為大寫字母。
6、比較運算:>,>=,<,<=,!=(<>),=(等值連接)
select * from emp where sal>=1500 and sal<=3000;--查找工資在1500到3000之間含兩者的所有員工的信息。
select * from emp where sal<>1500 and sal<>3000 and sal<>5000----把sal既不是1500也不是3000也不是5000的記錄輸出,資料庫中不等於有兩種表示:!= <>推薦使用第二種,對或取反是並且,對並且取反是或。
7、範圍查詢:between...and;not between...and
select * from emp where sal between 1500 and 3000--查找工資在1500到3000之間含兩者的所有員工的信息。
select * from emp where sal not between 1500 and 3000--查找工資在1500到3000之間不含兩者的所有員工的信息。
8、集合查詢:in(屬於若幹個孤立的值)
select * from emp where sal in (1500,3000,5000);
select * from emp where sal not in (15000,3000,5000);--把sal既不是1500也不是3000也不是5000的記錄輸出
9、空值查詢:null(沒有值,空值)
1)零和null是不一樣的,null表示空值,沒有值,零表示一個確定的值。
2)null不能參加的運算:<> != =
3)null可以參與的運算:is not is
select * from emp where comm is null;---輸出獎金為空的員工信息
select * from emp where comm is not null;---輸出獎金不為空的員工信息
select * from emp where comm <> null;---錯,輸出為空
select * from emp where comm != null;---錯,輸出為空
select * from emp where comm = null;---錯,輸出為空
4)任何類型的數據都允許為null
create table t1 (name nvarchar(20),cnt int,riqi datetime);
insert into t1 values (null,null,null);---正確
5)任何數字與null參與數學運算的結果永遠是null
---輸出每個員工的姓名年薪(包含獎金)comm假設是一年的獎金。
select empno,ename,sal*12+comm "年薪" from emp;---錯,null不能參與任何數據運算否則結果為空。
---正確的寫法:
select ename,sal*12+isnull(comm,0) "年薪" from emp;---isnull(comm,0)如果comm是null就返回零否則返回comm的值。
10、字元匹配查詢(模糊查詢)
1)格式:select 欄位的集合 from 表名 where 某個欄位的名字 like 匹配的條件。匹配額條件通常含有通配符。
2)通配符:
(1)%---表示任意0個或多個字元
select * from emp where ename like '%A%'---ename只要含有字母A就輸出。
select * from emp where ename like 'A%'---ename只要首字母為A就輸出。
select * from emp where ename like '%A'---ename只要尾字母為A就輸出。
(2)_(下劃線)---表示任意單個字元
select * from emp where ename like '_A%'---ename只要第二個字母為A就輸出。
[a-f]---表示a到f中的熱任意單個字元,只能是abcdef中的任意一個字元
select * from emp where ename like '_[A-F]%'---把ename中第二個字元是A或B或C或D或E或F的記錄輸出
[a,f]---表示a或f
[^a-c]---表示不是a也不是b也不是c的任意單個字元
select * from emp where ename like '_[^A-F]%'---把ename中第二個字元不是A也不是B也不是C也不是D也不是E也不是F的記錄輸出
(3)匹配的條件必須用單引號括起來,不能省略,也不能改用雙引號
(4)通配符作為不同字元使用的問題
預備操作:create table student
(name varchar(20) null
,age int);
insert into student values ('張三',88);
insert into student values ('tom',66);
insert into student values ('a_b',22);
insert into student values ('c%d',44);
insert into student values ('abc_fe',99);
insert into student values ('haobin',77);
insert into student values ('HaoBin',55);
insert into student values ('c%',33);
insert into student values ('long''s',100);
select * from student;
select * from student where name like '%\%%' escape '\'---把name中包含有%的輸出
select * from student where name like '%\_%' escape '\'---把name中包含有_的輸出
11、邏輯查詢:and or not
select * from emp where sal=1500 or sal=3000 or sal=5000;
12、排序運算:order by(以某個欄位排序),asc是升序預設可以不寫,desc是降序
1)order by a,b---a和b都是升序,如果不指定排序的標準,則預設是升序,升序用asc表示,預設可以不寫。
2)order by a,b desc---a升序,b降序,為一個欄位指定的排序標準並不會對另一個欄位產生影響。
3)order by a desc,b---a降序,b升序
4)order by a desc,b desc---a和b都降序,建議為每個欄位指定排序的標準。
5)例子:asc是升序的意思預設可以不寫,desc是降序
select * from emp order by sal;--預設升序排列
select * from emp order by deptno,sal;---先按照deptno升序排列,如果deptno相同,再按照sal升序排列
select * from emp order by deptno desc,sal;---先按照deptno降序排列,如果deptno相同,再按照sal升序排列。desc只對deptno產生影響不會對後面的sal產生影響。
select * from emp order by deptno,sal desc;---先按照deptno升序排列,如果deptno相同,再按照sal降序排列,desc只對sal產生影響不會對deptno產生影響。
13、聚合查詢(多行記錄返回一個值,通常用於統計分組的信息)
1)函數的分類:
(1)單行函數:每一行返回一個值
(2)多行函數:多行返回一個值
(3)聚合函數是多行函數
select lower(ename) from emp;---最終返回的是行lower()是單行函數
select max(sal) from emp;---返回行max()是多行函數
2)聚合函數分類:
(1)max()
(2)min()
(3)avg()---平均值
(4)count()---求個數
count(*)---返回表中所有記錄的個數
select count(*) from emp;---返回emp表所有記錄的個數
count(欄位名)---返回欄位值非空的記錄的個數,重覆的記錄也會被當做有效的記錄
select count(deptno) from emp;---deptno重覆的記錄被當做有效的記錄
select count(comm) from emp;---comm為null的記錄不會被當做有效的記錄
count(distinct 欄位名)---返回欄位不重覆並且非空的記錄的個數
select count (distinct deptno) from emp;---統計deptno不重覆的記錄的個數
3)註意的問題:
select max(sal),min(sal),count(*) from emp;---正確
select max(sal) "",min(sal) "",count(*) "" from emp;---正確
select max(sal),lower(ename) from emp;---錯誤,單行函數和多行函數不能混用
select max(sal) from emp;---正確,預設把所有的信息當做一組
14、分組聚合
1)group by
(1)格式:group by 欄位的集合
(2)功能:把表中的記錄按照欄位分成不同的組。
(3)例子:查詢不同部門的平均工資
select deptno,avg(sal) as "部門平均工資" from emp group by deptno
(4)理解group by a,b,c 的用法:先按a分組,如果a相同,再按b分組,如果b相同,再按c分組,最終統計的是最小分組的信息。
(5)使用了group by 之後 select 中只能出現分組之後的整體信息,不能出現組內的詳細信息。
2)having(對分組之後的信息進行過濾)
(1)having子句是用來對分組之後的數據進行過濾,因此使用having時通常會先使用group by。
(2)如果沒使用group by 但使用了having,則意味著having 把所有的記錄當做一組來進行過濾,極少用。
select count(*) from emp having avg(sal)>1000
(3)having子句出現的欄位必須是分組之後的組的整體信息,不允許出現組內的詳細信息。
(4)儘管select 欄位中可以出現別名,但having子句中不能出現欄位的別名,只能使用欄位最原始的名字。
(5)having 和where 的異同
相同:都是對數據進行過濾,只保留有效的數據;都不允許出現欄位的別名,只允許出現最原始的欄位的名字。
不同:where 是對原始的記錄過濾,having是對分組之後的記錄過濾。
where必須寫在having前面,順序不可顛倒,否則運行出錯。
例子:把工資大於2000,統計輸出部門平均工資大於3000的部門的部門編號、部門的平均工資
select deptno ,avg(sal)"平均工資",count(*)"部門人數",max(sal)"部門的最高工資"
from emp where sal>2000---where是對原始記錄進行過濾
group by deptno having avg(sal)>3000---對分組之後的記錄進行過濾
其中不可以將where 寫在having後面
15、連接查詢
1)定義:將兩個表或者兩個以上的表以一定的連接條件連接起來,從中檢索出滿足條件的數據。2)分類:
(1)內連接
select ... from A,B 的用法
產生的結果:行數是A和B的乘積,列數是A和B之和,即把A表的每一條記錄都和B表的每一條記錄組合在一起,形成笛卡爾積,即把B表的每一條記錄都和A表的每一條記錄組合在一起,形成笛卡爾積。
註意:select * from A,B輸出結果和select * from B,A一樣,即AB可以互換。
select ... from A,B where ...的用法
產生的笛卡爾積,用where中的條件進行過濾
select ... from A join B on...的用法
join是連接,AB互換結果不變。
SQL92和SQL99標準的區別
select ... from A,B where ...是SQL92標準
select ... from A join B on...是SQL99標準
輸出結果一樣
推薦使用SQL99標準:容易理解;on和where可以做不同的分工:on指定連接條件,where對連接之後臨時表的數據進行過濾。
例如:把工資大於2000的員工的姓名和部門的名稱輸出和工資的等級
SQL99標準
select "E".ename,"D".dname,"S".grade from emp "E" join dept "D"
on "E".deptno="D".deptno join salgrade "S"
on "E".sal>="S".losal and "E".sal<="S".hisal
where "E".sal>2000
SQL92標準
select "E".ename,"D".dname,"S".grade from emp "E", dept "D",salgrade "S"
where "E".sal>2000 and "E".deptno="D".deptno and ("E".sal>="S".losal and "E".sal<="S".hisal) (2)自連接:一張表自己和自己連接起來查詢數據。 select * from emp a,emp b where b.ename='張三' and a.deptno=b.deptno;--在員工表中查找與張三在同一個部門的員工的信息。
(3)外連接
select * from emp,dept where emp.deptno=dept.deptno;
(4)左外連接
select * from emp left outer join dept on emp.deptno=dept.deptno;
(5)右外連接
select * from emp right outer join dept on emp.deptno=dept.deptno;
(6)全外連接
select * from emp full outer join dept on emp.deptno=dept.deptno;
16、聯合:表和表之間的數據以縱向的方式連接在一起,前面均是橫向連接在一起。1)例子:輸出每個員工的姓名、工資、上司的姓名
select "E1".ename,"E1".sal,"E2".ename "上司的姓名" from emp "E1" join emp "E2"
on "E1".mgr="E2".empno
union
select ename,sal,'已是最大老闆' from emp where mgr is null
2)若幹個select子句要聯合成功的話,必須滿足兩個條件:
(1)若幹個select子句輸出的列數必須是相等的;
(2)若幹個select子句輸出列的數據類型至少是相容的。
17、top(最前面的若幹個記錄,專屬於SqlServer的語法,不可移植到其他資料庫)
select top 5 * from emp;
select top 15 percent * from emp;
select top 5 from emp;---錯的
18、複雜查詢:select\from\where\join\on\group\order\top\having的混合使用
1)查詢的順序:
select top...
from A
join B
on...
join C
on...
where...
group by...
having...
order by...
2)例子:把工資大於1500的所有員工按部門分組把部門平均工資大於2000的最高的前2個部門的編號、部門的名稱、部門平均工資的等級
(1)第一種寫法:
select "T".*,"D".dname,"S".grade from dept "D"
join(select top 2 "E".deptno,avg(sal) "avg_sal" from emp "E" join dept "D"
on "E".deptno="D".deptno join salgrade "S"
on "E".sal between "S".losal and "S".hisal
where "E".sal>1500
group by "E".deptno
having avg("E".sal)>2000
order by avg("E".sal) desc
) "T"
on "D".deptno ="T".deptno inner join salgrade “S”
on "T"."avg_sal" between "S".losal and "S".hisal
(2)第二種寫法:
select "T".*,"D".dname,"S".grade from dept "D"
join(select top 2 "E".deptno,avg(sal) "avg_sal" from emp
where sal>1500
group by deptno
having avg(sal)>2000
order by "avg_sal" desc
) "T"
on "D".deptno ="T".deptno join salgrade “S”
on "T"."avg_sal" between "S".losal and "S".hisal
19、分頁查詢
假設每頁顯示n條記錄,當前要顯示的是第m頁,表名是A,主鍵是A_id
select top n * from A where A_id not in (select top (m-1)*n A_id from emp);
20、嵌套子查詢
1)使用in的子查詢
select ename from emp where deptno in (select deptno from dept);
2)使用比較運算符的子查詢
select empno,ename from where sal>=all (select sal from sal where ename='張三');
3)使用存在量詞exists的子查詢
select ename from emp where exists (select * from dept);