【數據庫】SQL語言之數據查詢

前言:

現在我們來看看SQL語法的用法,包括查詢語句的類型、語法格式和對應的使用場景
這篇我們講數據查詢
數據查詢語言是數據庫最基本的應用,其語法較爲複雜,包括簡單查詢、帶條件查詢、連接查詢、子查詢、集合運算、數據分組、排序和限制等

1. 簡單查詢

日常查詢中 最常用的就是用過FROM子句實現的查詢

語法:

SELECT [ , ... ] FROM table_reference [ , ... ] 

使用方法:
SELECT項用於指定要查詢的列,FROM指定要從哪個表中查詢。
如果要查詢所有列,可以在SELECT後面使用*號,如果只查詢特定的列,可以直接在SELECT後面指定列名,列名之間用逗號(,)隔開。

例子1:
查詢training表中的所有列

SELECT * FROM training;
2. 關鍵字 DISTINCT

從SELECT的結果集中刪除所有重複的行,使結果集中的每行都是唯一的。去重複值查詢

例子:
利用distinct關鍵字來查詢員工的崗位和獎金,去除崗位和獎金相同的記錄。

select distinct job, bonus from sections;
3. 查詢列的選擇

例子1:
從多個表中查找多個列

其中,列a、b是表t1中的列,f1、f2是表t2中的列

SELECT a, b, f1, f2 FROM t1, t2;

例子2:
查兩個字段計算出來的

SELECT a+b FROM t1;

例子3:
如果某兩個或某幾個表正好有一些共同的列名,推薦使用表名限定列名。不限定列名可以得到查詢結果,但使用完全限定的表和列名稱,可以減少數據庫內部的處理工作量,從而提升查詢的返回性能

SELECT t1.f1, t2.f1 from t1, t2;
4. 別名

通過使用子句AS some_name,可以爲表名稱或列名稱指定另一個標題名顯示,一般創建別名是爲了讓列名稱的可讀性更強

  • 語法格式:
    列和表的SQL別名分別跟在相應的列名和表名後面,中間可以加或不加一個“AS”關鍵字。也可以用雙引號的方式來表示別名。

    例子:
    表名限定列名,查詢學號sid爲10的學生的數學成績和英語成績

select a.sid,a.score as math, b.score as english from math a,english b where a.sid = 10 and b.sid = 10;
5. 條件查詢

在SELECT語句中,可以通過設置條件以達到更精確的查詢。條件由表達式與操作符共同指定,且條件返回的值是TRUE,FALSE或UNKNOWN。查詢條件可以應用於WHERE子句,HAVING子句。

  1. 比較操作符
    “>, <,>=,<=, !=, <>,=”指定的比較查詢條件。當查詢條件中和數字比較,可以使用單引號引起,也可以不用,當和字符及日期類型的數據比較,則必須用單引號引起

  2. 邏輯操作符
    常用的邏輯操作符有AND、OR和NOT,他們的運算結果有三個值,分別爲TRUE、FALSE和NULL,其中NULL代表未知。他們運算優先級順序爲:NOT>AND>OR

    運算規則表

a b a AND b a OR b NOT a
TRUE TRUE TRUE TRUE FALSE
TRUE FALSE FALSE TRUE FALSE
TRUE NULL NULL TRUE FALSE
FALSE FALSE FALSE FALSE TRUE
FALSE NULL FALSE NULL TRUE
NULL NULL NULL NULL NULL
  1. 測試運算符
    測試運算符指定的範圍查詢條件
運算符 描述
IN/NOT IN 元素在/不在指定的集合中。
EXISTS/NOT EXISTS 存在/不存在符合條件的元素。
ANY/SOME 存在一個值滿足條件。SOME是ANY的同義詞。
ALL 全部值滿足條件。
BETWEEN…AND… 在兩者之間,例如a BETWEEN x AND y等效於a>= x and a <= y。
IS NULL/IS NOT NULL 等於/不等於NULL。
LIKE/NOT LIKE 字符串模式匹配/不匹配。
REGEXP 字符串與正則表達式相匹配,僅支持STRING類型。
REGEXP_LIKE 字符串與正則表達式相匹配,支持STRING類型和NUMBER類型。

例子1:
從表bonuses_depa中查詢崗位爲developer,且獎金>8000的職員信息

select * from bonuses_depa where job = 'developer' and bonus > 8000;

例子2:
從表bonuses_depa中查詢姓wang,且獎金在8500~9500之間的職員信息

select * from bonuses_depa where name like 'wang%' and bonus between 8500 and 9500;

補充:

通配符 %:表示任意數量的字符,包括無字符,用於like和not like語句中。
_:下劃線,表示確切的一個未知字符,用於like和not like語句中。

6. join連接查詢

實際應用中所需要的數據,經常會需要查詢兩個或兩個以上的表。這種查詢兩個或兩個以上數據表或視圖的查詢叫做連接查詢。連接查詢通常建立在存在相互關係的父子表之間。(只要在FROM子句中出現多個表時,數據庫就會執行連接)
大多數連接查詢包含至少一個連接條件,連接條件可以在FROM子句中也可以在WHERE子句中

舉個例子: 對A(4條記錄)和B(5條記錄)兩個表做不指定條件的連接查詢時,會得到20(4×5)條記錄

語法格式:

SELECT [ , ... ] FROM table_reference
                 [LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] | INNER]
                 JOIN table_reference
                 [ON { predicate } [ { AND | OR } condition ] [ , ... n ]]

注:table_reference 子句中可以是普通表、視圖、子查詢

  1. 內連接
    內連接的關鍵字爲inner join,其中inner可以省略。使用內連接,連接執行順序必然遵循語句中所寫的表的順序。

    例子:
    查詢員工ID、最高學歷和考試分數。使用training和education兩個相關的列(staff_id)做查詢操作

SELECT e.staff_id, e.higest_degree, t.score FROM education e JOIN training t ON (e.staff_id = t.staff_id);
  1. 外連接
  • 內連接所指定的兩個數據源處於平等的地位。而外連接不同,外連接以一個數據源爲基礎,將另外一個數據源與之進行條件匹配。
  • 內連接返回兩個表中所有滿足連接條件的數據記錄。外連接不僅返回滿足連接條件的記錄,還將返回不滿足連接條件的記錄。
  • 外連接又分爲左外連接、右外連接和全外連接。
  1. 左外連接
    又稱左連接,如圖所示,是指以左邊的表爲基礎表進行查詢。
    根據指定連接條件關聯右表,獲取基礎表以及和條件匹配的右表數據,未匹配條件的右表對應的字段位置填上NULL。

    例子:

SELECT e.staff_id, e.higest_degree, t.score FROM education e LEFT JOIN training t ON (e.staff_id = t.staff_id);

在這裏插入圖片描述

  1. 右外連接
    又稱右連接,是指以右邊的表爲基礎表,在內連接的基礎上也查詢右邊表中有記錄,而左邊的表中沒有記錄的數據(左邊用NULL值填充)。

    例子:

SELECT e.staff_id, e.higest_degree, t.score FROM education e RIGHT JOIN training t ON (e.staff_id = t.staff_id);

在這裏插入圖片描述

  1. 全外連接
    又稱全連接,是指除了返回兩個表中滿足連接條件的記錄,還會返回兩個表中不滿足連接條件的所有其它行(不匹配的另外一邊用NULL值填充)

    例子:

SELECT e.staff_id, e.higest_degree, t.score FROM education e FULL JOIN training t ON (e.staff_id = t.staff_id);

在這裏插入圖片描述

  1. 半連接
    半連接(Semi Join)是一種特殊的連接類型,在SQL中沒有指定的關鍵字,通過在WHERE後面使用IN或EXISTS子查詢實現。當IN/EXISTS右側的多行滿足子查詢的條件時,主查詢也只返回一行與IN/EXISTS子查詢匹配的行,而不是複製左側的行。

    例子:
    查看參加培訓的員工的教育信息。即使training表中的許多行可能與子查詢匹配(即同一個staff_id下有多個職員),也只需要從表training返回一行。

SELECT staff_id, higest_degree, education_note FROM education WHERE EXISTS (SELECT * FROM training WHERE education.staff_id = training.staff_id);
  1. 反連接
    反連接(Anti Join)是一種特殊的連接類型,在SQL中沒有指定的關鍵字,通過在WHERE後面使用NOT IN或NOT EXISTS子查詢實現。返回所有不滿足條件的行。這個關係的概念跟半連接相反。

    例子:

SELECT staff_id, higest_degree, education_note FROM education WHERE staff_id NOT IN (SELECT staff_id FROM training);
7. 子查詢

查詢是指在查詢、建表或插入語句的內部嵌入查詢,以獲得臨時結果集。
子查詢可以分爲相關子查詢非相關子查詢

子查詢類型 描述
相關子查詢 執行查詢的時候先取得外層查詢的一個屬性值,然後執行與此屬性值相關的子查詢,執行完畢後再取得外層查詢的下一個值,依次再來重複執行子查詢。
非相關子查詢 子查詢獨立於外層語句(主查詢),子查詢的執行不需要提前取得父查詢的值,只是作爲父查詢的查詢條件。查詢執行時子查詢和主查詢可分爲兩個獨立的步驟,即先執行子查詢,再執行主查詢。

子查詢可以出現在FROM子句、WHERE子句、以及WITH AS子句中。

例子1:
通過相關子查詢,查找每個部門中高出部門平均工資的人員

SELECT s1.last_name, s1.section_id, s1.salary
	  FROM staffs s1
	  WHERE salary >(SELECT avg(salary) FROM staffs s2 WHERE s2.section_id = s1.section_id)
	  ORDER BY s1.section_id;

對於staffs表的每一行,父查詢使用相關子查詢來計算同一部門成員的平均工資。相關子查詢爲staffs表的每一行執行以下步驟:
確定行的section_id。
然後使用section_id來評估父查詢。
如果此行中工資大於所在部門的平均工資,則返回該行。
對於staffs表的每一行,子查詢都將被計算一次。

例子2:
WITH子查詢:查詢培訓過big data課程的員工信息

WITH bigdata_staffs AS (select staff_id,exam_date from training where course_name = 'BIG DATA' )select * from bigdata_staffs;

例子3:
通過子查詢建立一個和表training具有相同表結構的表

CREATE TABLE training_new AS SELECT * FROM training WHERE  1<>1;

注:<>是不等於的意思,1<>1的條件不成立,所以子查詢不會返回數據

例子4:
通過子查詢向表training_new表中插入training表的所有數據

INSERT training_new SELECT * FROM training;
8. 合併結果集

除子查詢外,還可以使用集合運算符處理多個查詢的結果集,輸出最終結果

使用語法:

select_statement UNION [ALL] select_subquery

注:Union運算符:將多個查詢塊的結果集合併爲一個結果集輸出

使用方法:
• 每個查詢塊的查詢列數目必須相同。
• 每個查詢塊對應的查詢列必須爲相同數據類型或同一數據類型組。
•關鍵字ALL的意思是保持所有重複數據,而沒有ALL的情況下表示刪除所有重複數據。

理解:
在這裏插入圖片描述

例子:
現有兩個部門的員工信息,查詢獲得獎金超過7000的員工信息

SELECT staff_id, name, bonus FROM bonuses_depa1 WHERE bonus > 7000 UNION ALL SELECT
staff_id, name, bonus FROM bonuses_depa2 WHERE bonus > 7000 ;

在這裏插入圖片描述

9. 差異結果集

使用MINUS/ EXCEPT運算符。對查詢結果集的減法,計算存在於左邊查詢語句的輸出、而不存在於右邊查詢語句輸出的結果

比如:A minus B C就意味着將結果集A去除結果集B和結果集C中所包含的所有記錄後的結果,即在A中存在,而在B、 C中不存在的記錄

語法格式:

select_statement MINUS/EXCEPT select_statement2 [ ... ]

理解:
在這裏插入圖片描述

10. 數據分組
  1. GROUP BY
    數據庫查詢中,分組是一個非常重要的應用。分組是指將數據表中的記錄以某個或者某些列爲標準,值相等的劃分爲一組。

    語法格式

GROUP BY { column_name } [ , ... ]

使用方法:
○ GROUP BY子句中的表達式可以包含FROM子句中表,視圖的任何列,無論這些列是否出現在SELECT列表中。
○ GROUP BY子句對行進行分組,但不保證結果集的順序。 要對分組進行排序,請使用ORDER BY子句。
○ GROUPBY後的表達式可以使用括號,如: group by (expr1, expr2),或者 group by(expr1), (expr2)。但不支持 group by (expr1, expr2), expr3 格式。

例子:
該部門按照崗位和獎金分組,查詢每組員工數,結果按人數升序排序

select job, bonus, count(staff_id) sum from bonuses_depa group by(job,bonus) order by sum;

在這裏插入圖片描述
2. HAVING子句
與GROUP BY子句配合用來選擇特殊的組。HAVING子句將組的一些屬性與一個常數值比較,只有滿足HAVING子句中條件的組纔會被提取出來

語法格式:
HAVING condition [ , ... ]

例子:
查詢表sections中崗位人數大於3的各崗位員工總數。

select job, count(staff_id) from bonuses_depa group by job having count(staff_id) >3;
11. 數據排序
  1. ORDER BY子句

    使用ORDER BY子句對查詢語句返回的行根據指定的列進行排序。如果沒有ORDER BY子句,則多次執行的同一查詢將不一定以相同的順序進行行的檢索。

    語法格式:

ORDER BY { column_name | number | expression } [ ASC | DESC ][ NULLS FIRST | NULLS LAST ] [ , ... ]

使用方式:
○ column_name | number | expression 表示 order by 後面可以跟列名、數字、表達式(跟數字:order by 1 表示 根據查詢選擇列中第一個字段排序。跟表達式:order by(column1+column2) 表示根據column1與column2的和的大小來排序。)
○ ORDER BY語句默認按照升序對記錄進行排序。如果希望按照降序對記錄進行排序,請使用DESC關鍵字。
○ NULLS FIRST | NULLS LAST 關鍵字指定ORDER BY列中NULL值的排序位置,FIRST表示將NULL值排在最前面,LAST表示將NULL值排在最後面,若不指定該選項, ASC默認爲NULLS LAST, DESC默認爲NULLS FIRST。

例子:
查詢下表bonuses_depa中各工種的獎金信息,查詢結果先按bonus升序排列,然後按name降序排列

select * from bonuses_depa order by bonus,name desc;

在這裏插入圖片描述

12. 數據限制

數據限制功能包括兩個獨立的子句,LIMIT子句和OFFSET子句

  • LIMIT子句允許限制查詢返回的行。 可以指定偏移量,以及要返回的行數或行百分比。 可以使用此子句實現top-N報表。要獲得一致的結果,請指定ORDER BY子句以確保確定性排序順序
LIMIT { count | ALL }
  • OFFSET子句設置開始返回的位置
OFFSET start

使用方法
○ start:指定在返回行之前要跳過的行數。
○ count:指定要返回的最大行數。
○ start和count都被指定時,在開始計算要返回的count行之前會跳過start行
○ LIMIT 5,20與LIMIT 20 OFFSET 5及OFFSET 5 LIMIT 20 均表示跳過5行後輸出20行記錄

例子:
查詢下表 bonuses_depa中的員工信息。通過增加LIMIT 2 OFFSET 1限定查詢時跳過前1行後,查詢總共2行數據

SELECT name, job, bonus FROM bonuses_depa LIMIT 2 OFFSET 1;

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章