1. 基礎查詢語句
1.1 查詢表中所有數據
在SQL中,查詢表中所有數據是最基本的操作之一。通過使用SELECT * FROM table_name;
語句,可以獲取指定表中的所有記錄和列。例如,假設有一個名為employees
的表,包含員工的基本信息,執行以下語句:
SELECT * FROM employees;
將返回employees
表中的所有數據,包括員工的姓名、職位、工資等所有字段。這種查詢方式適用于需要查看表中完整數據的情況,但需要注意,當表中數據量較大時,返回的結果集可能會非常龐大,對性能有一定影響。
1.2 查詢指定列數據
在實際應用中,通常只需要查詢表中的部分列,而不是所有列。通過指定列名,可以更高效地獲取所需數據。例如,如果只想查詢employees
表中員工的姓名和工資,可以使用以下語句:
SELECT name, salary FROM employees;
這種方式不僅可以減少數據傳輸量,還能提高查詢效率,特別是在處理大型表時。此外,還可以通過AS
關鍵字為列名設置別名,使結果更易于理解。例如:
SELECT name AS employee_name, salary AS employee_salary FROM employees;
這將使查詢結果中的列名更具可讀性。
1.3 查詢滿足條件的數據
在SQL中,WHERE
子句用于篩選滿足特定條件的記錄。這是數據查詢中非常重要的功能,可以精確地獲取所需數據。例如,假設需要查詢工資大于5000的員工信息,可以使用以下語句:
SELECT * FROM employees WHERE salary > 5000;
此外,還可以使用多種條件運算符,如=
、<
、>
、<=
、>=
、<>
(不等于)等,以及邏輯運算符AND
、OR
、NOT
來組合復雜的條件。例如,查詢工資大于5000且職位為“經理”的員工信息:
SELECT * FROM employees WHERE salary > 5000 AND position = '經理';
這種條件查詢方式在實際應用中非常靈活,可以根據具體需求精確地篩選數據。
2. 條件查詢語句
2.1 單條件查詢
單條件查詢是 SQL 查詢中最為基礎且常見的類型,它通過一個簡單的條件篩選數據,能夠快速定位到符合特定要求的記錄。在實際應用中,單條件查詢的使用頻率非常高,尤其是在數據篩選和初步分析階段。
- 基本語法:
SELECT column_name(s) FROM table_name WHERE condition;
- 示例:假設有一個
employees
表,包含員工的姓名、職位、工資等信息,如果需要查詢工資大于 5000 的員工信息,可以使用以下語句:
這條語句會返回所有工資大于 5000 的員工記錄,包括他們的姓名、職位、工資等所有字段。SELECT * FROM employees WHERE salary > 5000;
- 性能分析:單條件查詢的性能主要取決于條件的復雜度以及表的索引情況。如果表中存在針對查詢條件的索引(如在
salary
字段上有索引),查詢效率會顯著提高。例如,在一個包含 100 萬條記錄的employees
表中,如果沒有索引,查詢可能需要掃描整個表,耗時較長;而如果在salary
字段上有索引,查詢時間可以縮短到毫秒級別。 - 應用場景:單條件查詢適用于簡單的數據篩選場景,如查詢某個特定時間段內的數據、某個特定狀態的數據等。例如,查詢最近一個月內注冊的用戶:
SELECT * FROM users WHERE registration_date >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
2.2 多條件查詢
多條件查詢允許通過多個條件組合來篩選數據,能夠更精確地定位到符合多個要求的記錄。通過邏輯運算符 AND
、OR
和 NOT
,可以實現復雜的條件組合,滿足多樣化的數據查詢需求。
- 基本語法:
- 使用
AND
:SELECT column_name(s) FROM table_name WHERE condition1 AND condition2;
- 使用
OR
:SELECT column_name(s) FROM table_name WHERE condition1 OR condition2;
- 使用
NOT
:SELECT column_name(s) FROM table_name WHERE NOT condition;
- 使用
- 示例:
- 查詢工資大于 5000 且職位為“經理”的員工信息:
SELECT * FROM employees WHERE salary > 5000 AND position = '經理';
- 查詢工資大于 5000 或職位為“經理”的員工信息:
SELECT * FROM employees WHERE salary > 5000 OR position = '經理';
- 查詢工資不大于 5000 的員工信息:
SELECT * FROM employees WHERE NOT salary > 5000;
- 查詢工資大于 5000 且職位為“經理”的員工信息:
- 性能分析:多條件查詢的性能同樣取決于條件的復雜度和索引情況。如果多個條件都涉及索引字段,查詢效率會更高。例如,在一個包含 100 萬條記錄的
employees
表中,如果salary
和position
字段都有索引,使用AND
條件的查詢可以快速定位到符合條件的記錄,查詢時間通常在毫秒級別。然而,如果條件涉及非索引字段,或者使用了復雜的邏輯運算符(如多個OR
),查詢性能可能會下降。 - 應用場景:多條件查詢適用于需要同時滿足多個條件的復雜數據篩選場景。例如,查詢某個部門中工資大于 5000 且入職時間在一年內的員工:
SELECT * FROM employees WHERE department = '銷售部' AND salary > 5000 AND hire_date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);
2.3 模糊查詢
模糊查詢用于查找符合某種模式的記錄,通常通過 LIKE
運算符實現。它允許使用通配符(如 %
和 _
)來匹配不確定的字符,能夠靈活地篩選出符合條件的記錄。
- 基本語法:
SELECT column_name(s) FROM table_name WHERE column_name LIKE pattern;
- 通配符:
%
:匹配任意數量的字符(包括零個字符)。_
:匹配任意單個字符。
- 示例:
- 查詢姓名以“張”開頭的員工信息:
SELECT * FROM employees WHERE name LIKE '張%';
- 查詢姓名為兩個字且第二個字為“偉”的員工信息:
SELECT * FROM employees WHERE name LIKE '_偉';
- 查詢姓名中包含“明”的員工信息:
SELECT * FROM employees WHERE name LIKE '%明%';
- 查詢姓名以“張”開頭的員工信息:
- 性能分析:模糊查詢的性能通常比精確查詢要低,尤其是當使用前導通配符(如
%
在模式的開頭)時。這是因為數據庫需要掃描整個字段來匹配模式,無法有效利用索引。例如,在一個包含 100 萬條記錄的employees
表中,使用LIKE '張%'
可以利用索引,查詢時間較快;而使用LIKE '%張'
則需要全表掃描,查詢時間會顯著增加。 - 應用場景:模糊查詢適用于需要查找符合某種模式的記錄的場景,如搜索功能、數據分類等。例如,查詢所有以“科技”結尾的公司名稱:
SELECT * FROM companies WHERE company_name LIKE '%科技';
3. 聚合函數查詢語句
聚合函數是 SQL 中用于對數據進行統計分析的重要工具,能夠對一組值進行計算并返回單個值。以下將從計算總和、最大值和最小值三個常見場景展開介紹。
3.1 計算總和
在數據分析中,計算總和是一種常見的需求,例如計算銷售額、工資總額等。SQL 提供了 SUM
函數來實現這一功能。
- 基本語法:
SELECT SUM(column_name) FROM table_name;
- 示例:假設有一個
sales
表,包含銷售訂單的金額信息,如果需要計算所有訂單的總銷售額,可以使用以下語句:
這條語句會返回所有訂單金額的總和,并將其命名為SELECT SUM(amount) AS total_sales FROM sales;
total_sales
。 - 性能分析:
SUM
函數的性能主要取決于表的大小和數據的分布情況。在大數據量的情況下,查詢可能會相對較慢。但如果表中存在針對amount
字段的索引,查詢效率會有所提升。例如,在一個包含 100 萬條記錄的sales
表中,使用SUM
函數計算總銷售額,查詢時間通常在秒級別。 - 應用場景:計算總和適用于需要對某一列數據進行累加的場景,如統計公司各部門的工資總額、計算產品庫存總量等。例如,計算每個部門的工資總額:
SELECT department, SUM(salary) AS total_salary FROM employees GROUP BY department;
3.2 計算最大值
在實際應用中,經常需要找出某一列中的最大值,例如最高工資、最高銷售額等。SQL 提供了 MAX
函數來實現這一功能。
- 基本語法:
SELECT MAX(column_name) FROM table_name;
- 示例:假設有一個
employees
表,包含員工的工資信息,如果需要查詢最高工資,可以使用以下語句:
這條語句會返回員工工資中的最大值,并將其命名為SELECT MAX(salary) AS max_salary FROM employees;
max_salary
。 - 性能分析:
MAX
函數的性能同樣取決于表的大小和數據的分布情況。如果表中存在針對查詢列的索引,查詢效率會更高。例如,在一個包含 100 萬條記錄的employees
表中,如果salary
字段上有索引,使用MAX
函數查詢最高工資,查詢時間通常在毫秒級別。 - 應用場景:計算最大值適用于需要找出某一列中最大值的場景,如確定最高銷售額、最高評分等。例如,查詢每個部門的最高工資:
SELECT department, MAX(salary) AS max_salary FROM employees GROUP BY department;
3.3 計算最小值
與計算最大值類似,計算最小值也是數據分析中的常見需求,例如最低工資、最低價格等。SQL 提供了 MIN
函數來實現這一功能。
- 基本語法:
SELECT MIN(column_name) FROM table_name;
- 示例:假設有一個
products
表,包含產品的價格信息,如果需要查詢最低價格,可以使用以下語句:
這條語句會返回產品價格中的最小值,并將其命名為SELECT MIN(price) AS min_price FROM products;
min_price
。 - 性能分析:
MIN
函數的性能表現與MAX
函數類似,主要取決于表的大小和數據的分布情況。如果表中存在針對查詢列的索引,查詢效率會顯著提高。例如,在一個包含 100 萬條記錄的products
表中,如果price
字段上有索引,使用MIN
函數查詢最低價格,查詢時間通常在毫秒級別。 - 應用場景:計算最小值適用于需要找出某一列中最小值的場景,如確定最低工資、最低庫存量等。例如,查詢每個部門的最低工資:
SELECT department, MIN(salary) AS min_salary FROM employees GROUP BY department;
4. 分組查詢語句
4.1 按單一字段分組
在 SQL 中,GROUP BY
子句用于將數據按照某個字段進行分組,以便對每個分組進行聚合計算。按單一字段分組是最基本的分組方式,能夠幫助我們快速了解數據在某個維度上的分布情況。
- 基本語法:
SELECT column_name, aggregate_function(column_name) FROM table_name GROUP BY column_name;
- 示例:假設有一個
employees
表,包含員工的部門和工資信息,如果需要計算每個部門的平均工資,可以使用以下語句:
這條語句會將員工按照部門分組,并計算每個部門的平均工資。SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department;
- 性能分析:按單一字段分組的性能主要取決于表的大小和分組字段的索引情況。如果分組字段上有索引,查詢效率會更高。例如,在一個包含 100 萬條記錄的
employees
表中,如果department
字段上有索引,使用GROUP BY
分組查詢,查詢時間通常在秒級別。 - 應用場景:按單一字段分組適用于需要對數據進行簡單分組統計的場景,如統計每個產品的銷售數量、每個客戶的訂單數量等。例如,統計每個產品的銷售數量:
SELECT product_id, COUNT(*) AS sales_count FROM orders GROUP BY product_id;
4.2 按多個字段分組
按多個字段分組可以同時根據多個維度對數據進行分組,能夠更細致地分析數據的分布情況。這種方式在實際應用中非常靈活,可以滿足復雜的統計需求。
- 基本語法:
SELECT column_name1, column_name2, aggregate_function(column_name) FROM table_name GROUP BY column_name1, column_name2;
- 示例:假設有一個
sales
表,包含銷售訂單的日期、產品和金額信息,如果需要計算每個日期和每個產品的總銷售額,可以使用以下語句:
這條語句會將銷售訂單按照日期和產品分組,并計算每個分組的總銷售額。SELECT sale_date, product_id, SUM(amount) AS total_sales FROM sales GROUP BY sale_date, product_id;
- 性能分析:按多個字段分組的性能同樣取決于表的大小和分組字段的索引情況。如果多個分組字段都有索引,查詢效率會更高。例如,在一個包含 100 萬條記錄的
sales
表中,如果sale_date
和product_id
字段都有索引,使用GROUP BY
分組查詢,查詢時間通常在秒級別。 - 應用場景:按多個字段分組適用于需要同時根據多個維度進行數據統計的場景,如統計每個部門每個職位的員工數量、每個地區每個產品的銷售額等。例如,統計每個部門每個職位的員工數量:
SELECT department, position, COUNT(*) AS employee_count FROM employees GROUP BY department, position;
4.3 分組后篩選
在分組查詢的基礎上,使用 HAVING
子句可以對分組后的結果進行篩選,以便進一步過濾數據。HAVING
子句的作用類似于 WHERE
子句,但它用于篩選分組后的聚合結果,而不是單條記錄。
- 基本語法:
SELECT column_name, aggregate_function(column_name) FROM table_name GROUP BY column_name HAVING condition;
- 示例:假設有一個
employees
表,包含員工的部門和工資信息,如果需要查詢平均工資大于 5000 的部門,可以使用以下語句:
這條語句會將員工按照部門分組,計算每個部門的平均工資,并篩選出平均工資大于 5000 的部門。SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department HAVING AVG(salary) > 5000;
- 性能分析:分組后篩選的性能主要取決于分組查詢的效率和篩選條件的復雜度。如果分組字段上有索引,查詢效率會更高。例如,在一個包含 100 萬條記錄的
employees
表中,如果department
字段上有索引,使用GROUP BY
和HAVING
子句進行篩選,查詢時間通常在秒級別。 - 應用場景:分組后篩選適用于需要對分組結果進行進一步篩選的場景,如篩選銷售額超過某個閾值的產品、篩選員工數量超過某個閾值的部門等。例如,篩選銷售額超過 10000 的產品:
SELECT product_id, SUM(amount) AS total_sales FROM sales GROUP BY product_id HAVING SUM(amount) > 10000;
5. 排序查詢語句
5.1 單字段排序
在 SQL 中,ORDER BY
子句用于對查詢結果按照指定字段進行排序,這是數據展示和分析中常用的功能之一。單字段排序是最基本的排序方式,能夠幫助我們快速了解數據在某個維度上的順序關系。
- 基本語法:
SELECT column_name(s) FROM table_name ORDER BY column_name [ASC|DESC];
ASC
表示升序排序(默認值),DESC
表示降序排序。
- 示例:假設有一個
employees
表,包含員工的姓名和工資信息,如果需要按照工資升序排序,可以使用以下語句:
如果需要按照工資降序排序,可以使用:SELECT name, salary FROM employees ORDER BY salary ASC;
SELECT name, salary FROM employees ORDER BY salary DESC;
- 性能分析:單字段排序的性能主要取決于表的大小和排序字段的索引情況。如果排序字段上有索引,查詢效率會顯著提高。例如,在一個包含 100 萬條記錄的
employees
表中,如果salary
字段上有索引,使用ORDER BY
進行排序,查詢時間通常在秒級別。如果沒有索引,排序操作可能會相對較慢,尤其是對于大數據量的表。 - 應用場景:單字段排序適用于需要按照某個字段的順序展示數據的場景,如按照時間順序展示訂單、按照成績高低展示學生排名等。例如,按照注冊時間降序展示用戶:
SELECT user_id, registration_date FROM users ORDER BY registration_date DESC;
5.2 多字段排序
多字段排序允許按照多個字段的順序對查詢結果進行排序,這在實際應用中非常靈活,可以滿足更復雜的排序需求。
- 基本語法:
SELECT column_name(s) FROM table_name ORDER BY column_name1 [ASC|DESC], column_name2 [ASC|DESC];
- 示例:假設有一個
employees
表,包含員工的部門、姓名和工資信息,如果需要先按照部門升序排序,再按照工資降序排序,可以使用以下語句:SELECT department, name, salary FROM employees ORDER BY department ASC, salary DESC;
- 性能分析:多字段排序的性能同樣取決于表的大小和排序字段的索引情況。如果多個排序字段都有索引,查詢效率會更高。例如,在一個包含 100 萬條記錄的
employees
表中,如果department
和salary
字段都有索引,使用多字段排序,查詢時間通常在秒級別。如果沒有索引,排序操作可能會相對較慢,尤其是對于大數據量的表。 - 應用場景:多字段排序適用于需要同時按照多個字段的順序展示數據的場景,如先按照地區排序,再按照銷售額排序;或者先按照日期排序,再按照優先級排序。例如,先按照產品類別排序,再按照銷售額降序展示銷售記錄:
SELECT category, product_id, amount FROM sales ORDER BY category ASC, amount DESC;
5.3 排序與分頁
在實際應用中,尤其是對于大數據量的表,我們通常需要對排序后的結果進行分頁展示,以便用戶可以逐頁查看數據。SQL 提供了 LIMIT
(在 MySQL 中)或 ROWNUM
(在 Oracle 中)等機制來實現分頁查詢。
- 基本語法:
- 在 MySQL 中:
SELECT column_name(s) FROM table_name ORDER BY column_name LIMIT offset, rows;
- 在 Oracle 中:
SELECT column_name(s) FROM (SELECT column_name(s), ROWNUM AS rnum FROM table_name WHERE ROWNUM <= end_row) WHERE rnum >= start_row;
- 在 MySQL 中:
- 示例:假設有一個
employees
表,包含員工的姓名和工資信息,如果需要按照工資降序排序,并分頁展示,每頁顯示 10 條記錄,查詢第 2 頁的數據,可以使用以下語句(以 MySQL 為例):
這條語句會跳過前 10 條記錄,返回第 11 到第 20 條記錄。SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 10, 10;
- 性能分析:排序與分頁的性能主要取決于表的大小、排序字段的索引情況以及分頁參數。如果排序字段上有索引,查詢效率會顯著提高。例如,在一個包含 100 萬條記錄的
employees
表中,如果salary
字段上有索引,使用排序與分頁查詢,查詢時間通常在秒級別。如果沒有索引,排序和分頁操作可能會相對較慢,尤其是對于大數據量的表。 - 應用場景:排序與分頁適用于需要對大量數據進行逐頁展示的場景,如分頁展示商品列表、分頁展示用戶評論等。例如,分頁展示訂單記錄,每頁顯示 20 條記錄:
SELECT order_id, order_date, amount FROM orders ORDER BY order_date DESC LIMIT 20, 20;
6. 連接查詢語句
6.1 內連接查詢
內連接查詢用于從兩個或多個表中返回匹配的記錄,只有當連接的表中存在滿足條件的記錄時,才會出現在結果集中。這是連接查詢中最常用的一種方式,能夠有效地整合多個表中的相關數據。
- 基本語法:
SELECT column_name(s) FROM table1 INNER JOIN table2 ON table1.column = table2.column;
- 示例:假設有一個
employees
表和一個departments
表,employees
表包含員工的基本信息,departments
表包含部門的信息。如果需要查詢每個員工所屬的部門名稱,可以使用以下語句:
這條語句會返回所有員工及其對應的部門名稱,只有那些在SELECT employees.name, departments.department_name FROM employees INNER JOIN departments ON employees.department_id = departments.department_id;
employees
表和departments
表中department_id
匹配的記錄才會出現在結果中。 - 性能分析:內連接查詢的性能主要取決于連接條件的復雜度和表的大小。如果連接字段上有索引,查詢效率會顯著提高。例如,在一個包含 100 萬條記錄的
employees
表和一個包含 10 萬條記錄的departments
表中,如果department_id
字段上有索引,內連接查詢的時間通常在秒級別。如果沒有索引,查詢可能會相對較慢,尤其是對于大數據量的表。 - 應用場景:內連接查詢適用于需要從多個表中提取相關數據的場景,如查詢學生的成績和對應的課程名稱、查詢訂單和對應的客戶信息等。例如,查詢每個訂單的客戶名稱和訂單金額:
SELECT customers.customer_name, orders.order_amount FROM customers INNER JOIN orders ON customers.customer_id = orders.customer_id;
6.2 左外連接查詢
左外連接查詢用于從左表中返回所有記錄,即使右表中沒有匹配的記錄,也會出現在結果集中。如果右表中沒有匹配的記錄,結果集中右表的字段將顯示為 NULL
。這種查詢方式在需要保留左表所有數據的情況下非常有用。
- 基本語法:
SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column = table2.column;
- 示例:假設有一個
employees
表和一個departments
表,如果需要查詢每個員工及其所屬的部門名稱,即使某些員工沒有分配部門,也可以使用以下語句:
這條語句會返回所有員工的記錄,即使某些員工的SELECT employees.name, departments.department_name FROM employees LEFT JOIN departments ON employees.department_id = departments.department_id;
department_id
在departments
表中沒有匹配的記錄,這些員工的部門名稱將顯示為NULL
。 - 性能分析:左外連接查詢的性能同樣取決于連接條件的復雜度和表的大小。如果連接字段上有索引,查詢效率會更高。例如,在一個包含 100 萬條記錄的
employees
表和一個包含 10 萬條記錄的departments
表中,如果department_id
字段上有索引,左外連接查詢的時間通常在秒級別。如果沒有索引,查詢可能會相對較慢,尤其是對于大數據量的表。 - 應用場景:左外連接查詢適用于需要保留左表所有數據的場景,如查詢所有學生及其對應的課程成績(即使某些學生沒有成績)、查詢所有客戶及其對應的訂單信息(即使某些客戶沒有訂單)等。例如,查詢所有客戶及其訂單金額:
SELECT customers.customer_name, orders.order_amount FROM customers LEFT JOIN orders ON customers.customer_id = orders.customer_id;
6.3 右外連接查詢
右外連接查詢與左外連接查詢相反,它從右表中返回所有記錄,即使左表中沒有匹配的記錄,也會出現在結果集中。如果左表中沒有匹配的記錄,結果集中左表的字段將顯示為 NULL
。這種查詢方式在需要保留右表所有數據的情況下非常有用。
- 基本語法:
SELECT column_name(s) FROM table1 RIGHT JOIN table2 ON table1.column = table2.column;
- 示例:假設有一個
employees
表和一個departments
表,如果需要查詢每個部門及其所屬的員工名稱,即使某些部門沒有員工,也可以使用以下語句:
這條語句會返回所有部門的記錄,即使某些部門的SELECT employees.name, departments.department_name FROM employees RIGHT JOIN departments ON employees.department_id = departments.department_id;
department_id
在employees
表中沒有匹配的記錄,這些部門的員工名稱將顯示為NULL
。 - 性能分析:右外連接查詢的性能同樣取決于連接條件的復雜度和表的大小。如果連接字段上有索引,查詢效率會更高。例如,在一個包含 100 萬條記錄的
employees
表和一個包含 10 萬條記錄的departments
表中,如果department_id
字段上有索引,右外連接查詢的時間通常在秒級別。如果沒有索引,查詢可能會相對較慢,尤其是對于大數據量的表。 - 應用場景:右外連接查詢適用于需要保留右表所有數據的場景,如查詢所有課程及其對應的學生信息(即使某些課程沒有學生)、查詢所有產品及其對應的訂單信息(即使某些產品沒有訂單)等。例如,查詢所有產品及其訂單數量:
SELECT products.product_name, COUNT(orders.order_id) AS order_count FROM products RIGHT JOIN orders ON products.product_id = orders.product_id GROUP BY products.product_id;
7. 子查詢語句
子查詢是 SQL 查詢中一種非常強大的工具,它允許在一個查詢語句中嵌套另一個查詢語句。子查詢可以用于多種場景,包括作為條件篩選數據、作為數據源提供數據,以及實現復雜的關聯查詢。以下將從子查詢作為條件、子查詢作為數據源和相關子查詢三個子課題展開論述。
7.1 子查詢作為條件
子查詢作為條件時,通常用于 WHERE
子句或 HAVING
子句中,通過返回一個值或一組值來篩選數據。這種方式可以實現復雜的條件篩選,尤其是當需要基于另一個查詢的結果來篩選數據時。
- 基本語法:
- 單值子查詢:
SELECT column_name(s) FROM table_name WHERE column_name operator (SELECT column_name FROM table_name WHERE condition);
- 多值子查詢:
SELECT column_name(s) FROM table_name WHERE column_name IN (SELECT column_name FROM table_name WHERE condition);
- 單值子查詢:
- 示例:
- 查詢工資高于平均工資的員工信息:
SELECT * FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
- 查詢與最高工資員工同部門的員工信息:
SELECT * FROM employees WHERE department_id = (SELECT department_id FROM employees WHERE salary = (SELECT MAX(salary) FROM employees));
- 查詢工資高于平均工資的員工信息:
- 性能分析:子查詢作為條件的性能主要取決于子查詢的復雜度和表的大小。如果子查詢返回的結果集較小,且主查詢的條件字段上有索引,查詢效率會較高。例如,在一個包含 100 萬條記錄的
employees
表中,使用單值子查詢查詢工資高于平均工資的員工,查詢時間通常在秒級別。 - 應用場景:子查詢作為條件適用于需要基于另一個查詢結果進行篩選的場景,如查詢特定條件下的數據、查詢與某個特定記錄相關的數據等。例如,查詢與某個特定客戶有相同訂單的其他客戶:
SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_id = (SELECT order_id FROM orders WHERE customer_id = 1001));
7.2 子查詢作為數據源
子查詢作為數據源時,通常用于 FROM
子句中,將子查詢的結果作為一個臨時表或派生表,供主查詢使用。這種方式可以實現復雜的多表查詢,尤其是當需要對多個表進行聯合查詢時。
- 基本語法:
SELECT column_name(s) FROM (SELECT column_name(s) FROM table_name WHERE condition) AS derived_table;
- 示例:
- 查詢每個部門工資最高的員工信息:
SELECT department_id, name, salary FROM (SELECT department_id, name, salary,ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rankFROM employees ) AS ranked_employees WHERE rank = 1;
- 查詢每個部門的平均工資和員工數量:
SELECT department_id, AVG(salary) AS avg_salary, COUNT(*) AS employee_count FROM employees GROUP BY department_id;
- 查詢每個部門工資最高的員工信息:
- 性能分析:子查詢作為數據源的性能主要取決于子查詢的復雜度和主查詢的復雜度。如果子查詢返回的結果集較小,且主查詢的條件字段上有索引,查詢效率會較高。例如,在一個包含 100 萬條記錄的
employees
表中,使用子查詢查詢每個部門工資最高的員工,查詢時間通常在秒級別。 - 應用場景:子查詢作為數據源適用于需要對多個表進行聯合查詢的場景,如查詢每個部門的統計數據、查詢每個產品的銷售數據等。例如,查詢每個產品的總銷售額和訂單數量:
SELECT product_id, SUM(amount) AS total_sales, COUNT(*) AS order_count FROM orders GROUP BY product_id;
7.3 相關子查詢
相關子查詢是指子查詢的執行依賴于主查詢的結果,即子查詢中包含主查詢的列或表。這種方式可以實現復雜的關聯查詢,尤其是當需要基于主查詢的每一行結果來動態生成子查詢時。
- 基本語法:
SELECT column_name(s) FROM table_name WHERE column_name operator (SELECT column_name FROM table_name WHERE condition);
- 示例:
- 查詢每個員工的工資與部門平均工資的比較:
SELECT e.name, e.salary, d.avg_salary FROM employees e JOIN (SELECT department_id, AVG(salary) AS avg_salaryFROM employeesGROUP BY department_id ) AS d ON e.department_id = d.department_id;
- 查詢每個員工的工資是否高于部門平均工資:
SELECT e.name, e.salary, d.avg_salary,CASE WHEN e.salary > d.avg_salary THEN '高于平均工資' ELSE '低于或等于平均工資' END AS salary_comparison FROM employees e JOIN (SELECT department_id, AVG(salary) AS avg_salaryFROM employeesGROUP BY department_id ) AS d ON e.department_id = d.department_id;
- 查詢每個員工的工資與部門平均工資的比較:
- 性能分析:相關子查詢的性能通常比普通子查詢要低,因為子查詢需要為每一行主查詢的結果動態執行。如果主查詢的表較大,且子查詢的條件字段上有索引,查詢效率會有所提升。例如,在一個包含 100 萬條記錄的
employees
表中,使用相關子查詢查詢每個員工的工資與部門平均工資的比較,查詢時間通常在秒級別。 - 應用場景:相關子查詢適用于需要基于主查詢的每一行結果動態生成子查詢的場景,如查詢每個員工的績效與部門平均績效的比較、查詢每個產品的銷售額與類別平均銷售額的比較等。例如,查詢每個產品的銷售額是否高于類別平均銷售額:
SELECT o.product_id, o.amount, c.avg_amount,CASE WHEN o.amount > c.avg_amount THEN '高于平均銷售額' ELSE '低于或等于平均銷售額' END AS amount_comparison FROM orders o JOIN (SELECT product_id, AVG(amount) AS avg_amountFROM ordersGROUP BY product_id ) AS c ON o.product_id = c.product_id;