一、多表查詢:根據特定的連接條件從不同的表中獲取所需的數據
多表查詢語法:
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column1 = table2.column2;
但要注意where 不要省了,省略where 即為笛卡爾集
笛卡爾集的產生條件:省略連接條件,連接條件無效
笛卡爾集的造成的影響: 第一個表中的所有行與第二個表中的所有行相連接,數據無效。
兩張表間有一個相同的字段,才好進行有效的多表查詢。
使用表別名和表前綴:
SELECT t1.column, t2.column FROM table1 t1, table2 t2 WHERE t1.column1 = t2.column2;
查詢時列名前,加表名或表別名前輟(如果字段在兩個表中是唯一的可以不加)
為表名定義別名,可以簡化SQL書寫,格式:“from 表名 別名”
如:from emp e,dept d
建議使用表的別名及表前綴,使用表別名可以簡化查詢,而使用表前綴則可以提高查詢性能。
多表查詢的另一種寫法:
聯接:內聯接 —— inner join
select emp.column,dept.column from emp join dept on(emp.column= dept.column)
注釋:INNER JOIN 與 JOIN 是相同的 。
聯接:外聯接 —— outer join ( left outer join, right outer join)
select emp.column,dept.column from emp left join dept on(emp.column= dept.column) where dept.column is null
注釋:可省略outer,以左表為主,右表中只顯示匹配左表的數據。
二、子查詢就是位於SELECT、UPDATE、或DELETE語句中內部的查詢
子查詢的分類:
獨立子查詢 —— 獨立子查詢可以獨立執行,不受外部查詢的影響
相關子查詢 —— 引用外部SQL語句中的一列或多列,需要與外部查詢聯合起來確定。
子查詢語法:
SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table);
子查詢(內部查詢)在執行主查詢之前執行一次,然后主查詢(外部查詢)會使用該子查詢的結果
子查詢的規則:
將子查詢括在括號中
將子查詢放置在比較條件的右側
只有在執行排序Top-N分析時,子查詢中才需要使用ORDER BY 子句
單行運算符用於單行子查詢,多行運算符用於多行子查詢
(1)單行子查詢:
即子查詢只返回一行結果,使用單行的比較運算符:= ,>, >= ,< , <= ,<>
select ename,job from emp where empno = (select empno from emp where mgr = 7902 );
使用聚合函數的子查詢
select ename,job,sal from emp where sal >(select avg(sal) from emp);
在HAVING子句中使用子查詢
select deptno,min(sal) from emp group by deptno having min(sal) > (select min(sal) from emp where deptno = 20);
在FROM 子句中使用子查詢
select ename,job,sal from (select * from emp) as t1; -- 注意:from子查詢后邊一定要跟別名
單行子查詢中的常見錯誤:
1. 子查詢的結果返回多於一行
2. 子查詢中不能包含ORDER BY子句
3. 子查詢內部沒有返回行,如下語句可以正確執行,但沒有數據返回
select empno,ename from emp where sal = (select sal from emp where deptno = 20); --Error 子句中無返回行,或返回多行均為錯誤。 select empno,ename from emp where sal >(select avg(sal) from emp order by empno); --Error 子句中不能包含order by
(2)多行子查詢:
即子查詢返回多行結果 —— 返回結果要采用多行比較運算符(in <not in>、any、all、some)。
在多行子查詢中使用IN 操作符
select empno,ename,job from emp where sal in (select max(sal) from emp group by deptno);
--IN 給定的值是否與子查詢或列表中的任一值相匹配 就成立。
--NOT IN 給定的值是否與子查詢或列表中的所有值都不匹配 就成立。
注意:要防止子查詢返回空值,因為只要空值成為子查詢的一部分,就不能用notin運算符。
select empno,ename,job from emp where sal < any(select avg(sal) from emp group by deptno);
--ALL 對所有數據都滿足條件,整個條件才成立
--ANY 只要有一條數據滿足條件,整個條件就成立
(3)多列子查詢:
子查詢只返回多列結果,多列子查詢分為:成對比較多列子查詢、非成對比較多列子查詢
成對比較 —— 查詢工資為部門最高的記錄
select * from scott.emp where (sal,job) in(select max(sal),job from scott.emp group by job);
非成對比較 —— 實現了與上述類似的功能
select * from scott.emp where sal in (select max(sal) from scott.emp group by job) and job in (select distinct job from scott.emp);
(4)相關子查詢:
子查詢中使用了主查詢中的某些字段,
相關子查詢(也稱為重復子查詢)的查詢中,子查詢依靠外部查詢獲得值。這意味着子查詢是重復執行的,主查詢選擇的每一行均執行一次子查詢。
--查詢工資高於同一部門的員工的部門號,姓名,工資
select deptno,ename,sal from emp outer where sal >(select avg(sal) from emp inner where inner.deptno = outer.deptno);
(5) 嵌套子查詢:即位於子查詢內部的子查詢,嵌套可達32層(實際工作中嵌套超過兩層就要被打PP了-.-),然而應盡量避免使用嵌套子查詢,使用表連接的查詢性能會更高。
三、分頁
方法1:適用於 SQL Server 2000/2005
SELECT TOP 10 * FROM tableName WHERE id NOT IN ( SELECT TOP 10*(pageNum-1) id FROM tableName ORDER BY id ) ORDER BY id
方法2:適用於 SQL Server 2000/2005
SELECT TOP pageSize * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY id) AS rows,* FROM tableName ) aliasName WHERE rows > pageSize*(currentPage-1) -- pageSize 每頁顯示條數 -- currentPage 當前頁數 -- aliasName 意指別名