前面的幾篇文章中,咱們大致上介紹了 SQL 中基本的建立、查詢語句,甚至也學習了相對複雜的鏈接查詢和子查詢,這些基本功相信你也必定掌握的不錯,那麼本篇則着重介紹幾個技巧方面的關鍵字,可以讓你更快更有效率的寫出一些 SQL。java
在實際的項目中,有時候咱們的表名、字段名過於複雜以至於咱們的 SQL 寫出來過長、過於複雜,這時候咱們每每會經過起別名的方式將一些名字較長、較爲複雜的字段或是表名簡化。git
咱們可使用別名(Alias)來對數據表或者列進行臨時命名,既然是別名,也就是說並不會修改原表或列的原始名稱,僅僅用於當前查詢的簡介化顯示。程序員
給表起別名:github
select * from person as p where p.id = 1;
一旦爲表執行了別名,那麼本次查詢的子查詢語句中均可以直接引用別名替代原表的引用。數據庫
給列起別名:微信
select name as n,age as a from perosn;
除了使用關鍵字 as 來給表或是列起別名外,還能夠直接使用空格字符達到一樣的效果,可是我的認爲要麼所有使用 as 進行別名,要麼所有使用空格進行別名,不要交叉使用使得你的 SQL 複雜又難以看懂。函數
有時候,咱們的數據庫中會存在兩條徹底同樣的數據,咱們也叫作冗餘數據,固然不但願在查詢數據的時候查出來這麼些冗餘的重複數據,咱們要把它們過濾掉。學習
LeetCode 上的一道簡單題:測試
有一個courses 表 ,有: student (學生) 和 class (課程)。 請列出全部超過或等於5名學生的課。 例如,表: +---------+------------+ | student | class | +---------+------------+ | A | Math | | B | English | | C | Math | | D | Biology | | E | Math | | F | Computer | | G | Math | | H | Math | | I | Math | +---------+------------+ 應該輸出: +---------+ | class | +---------+ | Math | +---------+
你能夠花個一分鐘思考一下,運用咱們以前的基本功,應該是不難的。code
顯然是須要用到分組的,想要統計每門課有多少人選,就得按照學科進行分組,每一個分組內就是該門學科選修的學生記錄。
那麼 SQL 語句也就信手拈來了:
select class from courses group by class having count(student) >=5
可是你提交後在海量測試用例下,會返回給你解答錯誤的提示,不信你試試,問題出在哪?
問題就出如今冗餘數據這個邊界條件沒有被考慮,若是 A 選了兩次 Math,當咱們對 Math 這個分組進行計數時就會多算一次選 Math 的人數,實際上這是不符合邏輯的,咱們須要過濾掉那些重複選擇的數據記錄。
解決方案以下:
select class from courses group by class having count(distinct student) >=5
有些人可能看出來了,咱們在 count 函數的列參數前添加了一個 distinct 關鍵字,它表示若是 student 列的值重複出現的話只計數一次。
固然,distinct 除了能夠在聚合函數中使用外,也能夠直接用在查詢語句的列篩選階段,例如:
//取出全部的學生,不容許重複名字的學生同時出現 select distinct name from students
UNION 運算符能夠將一個或多個 SELECT 語句的結果鏈接組合成一個結果集,但要求兩個或多個結果具備相同數量的列,列的數據類型相同,舉個例子:
構建一個學生表:
+----+------+----------+-------+ | id | name | uNo | fees | +----+------+----------+-------+ | 1 | 張三 | 15263501 | 18000 | | 2 | 李四 | 15263506 | 15960 | | 3 | 王二 | 15263512 | 2500 | +----+------+----------+-------+
學生表主要有學生的姓名,學號和學費。
構建一個教師表:
+----+--------+------+--------+ | id | name | tNo | salary | +----+--------+------+--------+ | 1 | 李老師 | 1001 | 10000 | | 2 | 楊老師 | 1002 | 15000 | | 3 | 曹老師 | 1030 | 5000 | +----+--------+------+--------+
如今有一個需求,須要拿到全校全部人的姓名和編號,包括學生和老師。通常來講,咱們兩次 select 查詢就行了,可是無法合併在一個結果集中顯示,這是一個問題。
因而咱們可使用 union 來鏈接兩個結果並在一張表中顯示出來:
select name,uNo from students union select name,tNo from teacher
查詢結果:
+--------+----------+ | name | uNo | +--------+----------+ | 張三 | 15263501 | | 李四 | 15263506 | | 王二 | 15263512 | | 李老師 | 1001 | | 楊老師 | 1002 | | 曹老師 | 1030 | +--------+----------+
看起來是否是直觀了不少,除此以外的是,若是兩個結果集中存在徹底重複的數據記錄,合併後的結果集中不會重複出現該數據記錄。
固然了,若是你不須要在合併結果集的時候刪除掉重複的數據行,你能夠轉而使用關鍵字 UNION ALL 替代 UNION。
TOP 子句用於從一張數據表中取回前 N 個或者 X% 的記錄,可是須要注意的是,只有 SQLserver 數據庫實現是支持 TOP 的,各自有各自的關鍵字做爲替代,例如 MySQL 使用 LIMIT 關鍵字,Oracle 使用 ROWNUM 關鍵字。
例如:
select * from students limit 2;
MySQL 數據庫取出前兩條數據,等效的 Oracle 數據庫寫法:
select * from students rownum <= 2
以上的一些關鍵字雖然逐個看起來很簡單,但有時候可能會幫上你大忙的,不要忘記使用它們!。