sql經典實例_讀書筆記 前三章

sql經典實例_讀書筆記

溫故SQL以及數據庫相關知識

1、檢索記錄

select * from emp  //檢索所有列
where dep = 10  //選擇出指定行
or comm is not null
or sal <= 2000 and dep=20//滿足多個條件

select ename,dep,sal from emp //篩選出列
select sal as sale,com as commission from emp //縮寫,創建別名

select * from (select sal sa salary,com as commission from emp
              ) x where salary < 5000 //在where子句中引用別名列,無法直接引用

將含有別名列的查詢放入內嵌視圖,就可以在外層查詢中引用別名列。爲什麼要這麼做
呢? WHERE 子句會比 SELECT 子句先執行,就最初那個失敗的查詢例子而言,當 WHERE 子句
被執行時,SALARY 和 COMMISSION 尚不存在。直到 WHERE 子句執行完畢,那些別名列纔會生
效。然而,FROM 子句會先於 WHERE 子句執行。如果把最初的那個查詢放入一個 FROM 子句,其查詢結果會在最外層的 WHERE 子句開始之前產生,這樣一來,最外層的 WHERE 子句就能
“看見”別名列了。當表裏的某些列沒有被恰當命名的時候,這個技巧尤其有用

在本例中,內嵌視圖的別名爲 X。並非所有數據庫都需要給內嵌視圖取別名,
但對於某些數據庫而言,確實必須如此。不過,所有的數據庫都支持這一
點。

串聯多列

使用 CONCAT 函數可以串聯多列的值。在 DB2、Oracle 和 PostgreSQL 中,“||”是 CONCAT 函數的快捷方式,在 SQL Server 中則爲“+”。

//在SELECT語句裏使用條件邏輯

 select ename,sal,
	case when sal <= 2000 then 'UNDERPAID'
 		when sal >= 4000 then 'OVERPAID'
 		else 'OK'
 	end as status
 from emp

CASE 表達式能對查詢結果執行條件邏輯判斷。你可以爲 CASE 表達式的執行結果取一個別名,使結果集更有可讀性。

限定返回行數
//MySQL 和 PostgreSQL使用 LIMIT 子句。
1 select *
2 from emp limit 5

//Oracle
//對於 Oracle 而言,通過在 WHERE 子句中限制 ROWNUM 的值來獲得指定行數的結果集。
1 select *
2 from emp
3 where rownum <= 5

//SQL Server  使用 TOP 關鍵字限定返回行數。
1 select top 5 *
2 from emp
隨機返回若干行記錄
//MySQL 把內置函數 RAND 和 LIMIT、ORDER BY 結合使用。
1 select ename,job
2 from emp
3 order by rand() limit 5
//Oracle 在內置包 DBMS_RANDOM 裏可以找到 VALUE 函數,把該內置函數和 ORDER BY、內置函數 ROWNUM 結合使用。
1 select *
2 from (
3 select ename, job
4 from emp
6 order by dbms_random.value()
7 )
8 where rownum <= 5
//SQL Server 同時使用內置函數 NEWID 和 TOP、ORDER BY 來返回一個隨機結果集。
1 select top 5 ename,job
2 from emp
3 order by newid()
查找Null值
//要判斷一個值是否爲 Null,必須使用 IS Null。
1 select *
2 from emp
3 where comm is null
把Null值轉換爲實際值
//使用 COALESCE 函數將 Null 值替代爲實際值。
1 select coalesce(comm,0)
2 from emp
查找匹配項
//你想從編號爲 10 和 20 的兩個部門中找到名字中含有字母 I 或職位以 ER 結尾的人。
//結合使用 LIKE 運算符和 SQL 通配符 %。
1 select ename, job
2 from emp
3 where deptno in (10,20)
4 and (ename like '%I%' or job like '%ER')

2、查詢結果排序 order by

以指定順序返回查詢結果
使用 ORDER BY 子句。
1 select ename,job,sal
2 from emp
3 where deptno = 10
4 order by sal asc
//默認情況下,ORDER BY會做升序排列,因此 ASC 子句是可選項。相應地,也可以通過指定 DESC 執行降序排列。
// order by sal desc
多字段排序
 ORDER BY 子句中列出不同的排序列,以逗號分隔。
1 select empno,deptno,sal,ename,job
2 from emp
3 order by deptno, sal desc
依據子串排序
//望從 EMP 表檢索員工的名字和職位,並且按照職位字段的最後兩個字符對檢索結果進行排序
//DB2、MySQL、Oracle 和 PostgreSQL 在 ORDER BY 子句裏使用 SUBSTR 函數。
select ename,job
 from emp
 order by substr(job,length(job)-2)
//SQL Server 在 ORDER BY 子句裏使用 SUBSTRING 函數。
select ename,job
 from emp
 order by substring(job,len(job)-2,2)
對含有字母和數字的列排序
//有混合了字母和數字的數據,希望按照字母部分或者數字部分來排序
排序時對Null值的處理
//對可能爲 Null 的列進行升序排列或者降序排列。
1 select ename,sal,comm
2 from emp
3 order by 3
1 select ename,sal,comm
2 from emp
3 order by 3 desc
//但是,如果你希望採用與非 Null 值列不同的方式來排列 Null 值,例如,你可能想把非 Null 值以升序排列或降序排列,而把全部 Null 值都放到最後面,那麼你就要使用 CASE 表達式來動態調整排序項。
依據條件邏輯動態調整排序項
//例如,如果 JOB 等於 SALESMAN,就要按照 COMM 來排序;否則,按照 SAL 排序
1 select ename,sal,job,comm
2 from emp
3 order by case when job = 'SALESMAN' then comm else sal end
//可以利用 CASE 表達式來動態調整結果的排序方式。
select ename,sal,job,comm,
 case when job = 'SALESMAN' then comm else sal end as ordered
 from emp
 order by 5

3、多表查詢 (連接查詢和集合運算)

疊加兩個行集
使用集合運算 UNION ALL 合併多個表中的行。
1 select ename as ename_and_dname, deptno
2 	from emp
3  where deptno = 10
4  union all
5 select '----------', null
6 	from t1
7  union all
8 select dname, deptno
9 	from dept
合併相關行
//一個連接查詢的例子。更準確地說,它是內連接中的相等連接。連接查詢是一種把來自兩個表的合併起來的操作。對於相等連接而言,其連接條件依賴於某個相等條件(例如,一個表的部門編號和另一個表的部門編號相等)。
1 select e.ename, d.loc
2 from emp e, dept d
3 where e.deptno = d.deptno
4 and e.deptno = 10
查找兩個表中相同的行
//可以把多個表中所有必要的列都連接起來,以獲得正確的結果。也可以使用集合運算INTERSECT 來替代連接查詢,並返回兩個表的交集(相同的行)。
MySQL 和 SQL Server 
使用多個條件把 EMP 表和視圖 V 連接起來。
1 select e.empno,e.ename,e.job,e.sal,e.deptno
2 	from emp e, V
3 	where e.ename = v.ename
4 		and e.job = v.job
5 		and e.sal = v.sal
除此之外,也可以使用 JOIN 子句執行同樣的連接查詢。
1 select e.empno,e.ename,e.job,e.sal,e.deptno
2 	from emp e join V
3 	  on ( e.ename = v.ename
4 		  and e.job = v.job
5 		  and e.sal = v.sal)
查找只存在於一個表中的數據
從一個表檢索與另一個表不相關的行
兩個表有相同的鍵,你想在一個表裏查找與另一個表不相匹配的行。例如,你想找出哪些部門沒有員工
新增連接查詢而不影響其他連接查詢
你已經有了一個查詢語句,它可以返回你想要的數據。你需要一些額外信息,但當你試圖獲取這些信息的時候,卻丟失了原有的查詢結果集中的數據。例如,你想查找所有員工的信息,包括他們所在部門的位置,以及他們收到獎金的日期
確定兩個表是否有相同的數據
你想知道兩個表或兩個視圖裏是否有相同的數據(行數和值)
識別並消除笛卡兒積
你想執行一個聚合操作,但查詢語句涉及多個表。你希望確保表之間的連接查詢不會干擾聚合操作。例如,你希望計算部門編號爲 10 的員工的工資總額以及獎金總和。因爲有部分員工多次獲得獎金,所以在 EMP 表和 EMP_BONUS 表連接之後再執行聚合函數 SUM,就會得出錯誤的計算結果
組合使用連接查詢與聚合函數
你想從多個表中返回缺失值。找到存在於 DEPT 表而不存在於 EMP 表的數據(即沒有員工的部門)需要使用外連接
解決方案
使用全外連接(full outer join),基於一個共同值從兩個表中返回缺失值。
從多個表中返回缺失值
在運算和比較中使用Null
1. 問題
Null 不會等於或不等於任何值,甚至不能與其自身進行比較,但是你希望對從 Null 列返回的數據進行評估,就像評估具體的值一樣。例如,你想找出 EMP 表裏業務提成(COMM列)比員工 WARD 低的所有員工。檢索結果應該包含業務提成爲 Null 的員工。
2. 解決方案
使用如 COALESCE 這樣的函數把 Null 轉換爲一個具體的、可以用於標準評估的值。
1 select ename,comm
2 from emp
3 where coalesce(comm,0) < ( select comm
4 from emp
5 where ename = 'WARD' )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章