99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)大數(shù)據(jù)時(shí)代【干貨】2小時(shí)用AI完成的SQL教程也太贊了吧,不推薦deepseek
【干貨】2小時(shí)用AI完成的SQL教程也太贊了吧,不推薦deepseek
2025-02-25
收藏

以下文章來(lái)源于數(shù)有道 ,作者數(shù)據(jù)星爺

SQL查詢是數(shù)據(jù)分析工作的基礎(chǔ),也是CDA數(shù)據(jù)分析師一級(jí)的核心考點(diǎn),人工智能時(shí)代,AI能為我們節(jié)省多少工作量?本來(lái)想用deepseek部署,被卡出三界外,不在五行中,后來(lái)選擇了通義靈碼。

環(huán)境

AI環(huán)境:VScode+通義靈碼

練習(xí)網(wǎng)站:https://sqlfiddle.com/postgresql/online-compiler

1. 基礎(chǔ)概念

1.1 數(shù)據(jù)庫(kù)和表的概念

數(shù)據(jù)庫(kù):數(shù)據(jù)庫(kù)是一個(gè)有組織的數(shù)據(jù)集合,通常以電子表格的形式存儲(chǔ)。它由多個(gè)表組成,每個(gè)表代表一種特定類型的數(shù)據(jù)集合。

:表是數(shù)據(jù)庫(kù)中數(shù)據(jù)的基本存儲(chǔ)單位,類似于Excel中的工作表。表由行(記錄)和列(字段)構(gòu)成。每一行代表一條記錄,每一列代表一個(gè)屬性。

例如,在一個(gè)電商數(shù)據(jù)庫(kù)中,可能會(huì)有以下幾張表:

  • users 表:存儲(chǔ)用戶信息,如用戶ID、用戶名、郵箱等。
  • orders 表:存儲(chǔ)訂單信息,如訂單ID、用戶ID、訂單日期等。
  • products 表:存儲(chǔ)商品信息,如商品ID、名稱、價(jià)格等

1.2 SQL語(yǔ)言的基本結(jié)構(gòu)

SQL(Structured Query Language,結(jié)構(gòu)化查詢語(yǔ)言)是一種用于管理和操作關(guān)系型數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)語(yǔ)言。它的基本結(jié)構(gòu)包括以下幾個(gè)部分:

  • SELECT:用于從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù)。
  • FROM:指定要查詢的表。
  • WHERE:用于過濾數(shù)據(jù),只返回滿足條件的記錄。
  • GROUP BY:用于將結(jié)果集按一個(gè)或多個(gè)列進(jìn)行分組。
  • HAVING:用于在分組后進(jìn)一步過濾數(shù)據(jù)。
  • ORDER BY:用于對(duì)結(jié)果集進(jìn)行排序。
  • LIMIT:用于限制返回的結(jié)果數(shù)量。

1.3 示例

假設(shè)我們有一個(gè)名為 users 的表,包含以下字段

  • id (用戶ID)
  • name (用戶名)
  • email (用戶郵箱)

我們可以編寫一個(gè)簡(jiǎn)單的SQL查詢來(lái)獲取所有用戶的姓名和郵箱:

SELECT name, email FROM users;

如果我們只想獲取名字中包含 "張" 的用戶,可以使用 WHERE 子句:

SELECT name, email
FROM users
WHERE name LIKE '%張%';

1.4 總結(jié)

通過理解數(shù)據(jù)庫(kù)和表的概念以及SQL語(yǔ)言的基本結(jié)構(gòu),你可以開始構(gòu)建簡(jiǎn)單的查詢語(yǔ)句來(lái)檢索和操作數(shù)據(jù)。這是學(xué)習(xí)SQL的基礎(chǔ),后續(xù)我們將在此基礎(chǔ)上深入學(xué)習(xí)更復(fù)雜的查詢和操作。

2. 數(shù)據(jù)檢索

數(shù)據(jù)檢索是SQL中最常用的操作之一,它允許你從數(shù)據(jù)庫(kù)中提取所需的數(shù)據(jù)。我們將詳細(xì)講解如何使用SELECT語(yǔ)句及其相關(guān)子句來(lái)實(shí)現(xiàn)各種數(shù)據(jù)檢索操作。

2.1 使用 WITH 子句創(chuàng)建臨時(shí)表

首先,我們創(chuàng)建一個(gè)包含10條員工數(shù)據(jù)的臨時(shí)表 employees。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)

2.2 使用 SELECT 語(yǔ)句從單個(gè)表中檢索數(shù)據(jù)

示例 要獲取所有員工的姓名和部門:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT name, department
FROM employees;

結(jié)果:

2.3 使用 WHERE 子句過濾數(shù)據(jù)

示例 要獲取工資大于5000的員工信息:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT name, salary
FROM employees
WHERE salary > 5000;

結(jié)果

2.4 使用 ORDER BY 排序結(jié)果集

示例 要按工資從高到低排序員工信息:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT name, salary
FROM employees
ORDER BY salary DESC;

結(jié)果

2.5 使用 LIMIT 限制返回行數(shù)

示例 要獲取前5名最高工資的員工信息,并按工資降序排序:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5; 

結(jié)果

2.6 組合使用多個(gè)子句

示例 要獲取屬于 "銷售部" 的前3名最高工資的員工信息,并按工資降序排序:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT name, salary
FROM employees
WHERE department = '銷售部'
ORDER BY salary DESC
LIMIT 3;

結(jié)果

2.7 總結(jié)

通過上述示例,你可以看到如何使用 WITH 子句創(chuàng)建一個(gè)臨時(shí)表,并在此基礎(chǔ)上進(jìn)行各種數(shù)據(jù)檢索操作。這些示例涵蓋了 SELECT、WHERE、ORDER BY 和 LIMIT 的基本用法,幫助你更好地理解和驗(yàn)證查詢結(jié)果。

  • 使用SELECT語(yǔ)句從單個(gè)表中檢索數(shù)據(jù)
  • 使用WHERE子句過濾數(shù)據(jù)
  • 使用ORDER BY排序結(jié)果集
  • 使用LIMIT限制返回行數(shù)

3. 聚合與分組

使用COUNT(), SUM(), AVG(), MAX(), MIN()等聚合函數(shù)

使用GROUP BY對(duì)數(shù)據(jù)進(jìn)行分組

3.1 使用 WITH 子句創(chuàng)建臨時(shí)表

首先,我們創(chuàng)建一個(gè)包含10條員工數(shù)據(jù)的臨時(shí)表 employees。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)

3.2 聚合函數(shù)

聚合函數(shù)用于對(duì)一組值執(zhí)行計(jì)算并返回單個(gè)值。常用的聚合函數(shù)包括:

  • COUNT():計(jì)算行數(shù)。
  • SUM():計(jì)算總和。
  • AVG():計(jì)算平均值。
  • MAX():返回最大值。
  • MIN():返回最小值。

示例- count 計(jì)算總員工數(shù):

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT COUNT(*) AS total_employees
FROM employees;

結(jié)果:

total_employees
10

示例-sum 計(jì)算所有員工的總薪水:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT SUM(salary) AS total_salary
FROM employees;

結(jié)果:

total_salary
59000

示例-avg 計(jì)算所有員工的平均薪水:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT AVG(salary) AS average_salary
FROM employees;

結(jié)果:

average_salary
5900.00

示例-max 返回最高薪水:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT MAX(salary) AS max_salary
FROM employees;

結(jié)果:

max_salary
8000

示例-min 返回最低薪水:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT MIN(salary) AS min_salary
FROM employees;

結(jié)果:

min_salary
4000

3.3 使用 GROUP BY 進(jìn)行分組

GROUP BY 子句用于將結(jié)果集按一個(gè)或多個(gè)列進(jìn)行分組,通常與聚合函數(shù)一起使用。

示例-count 按部門分組,計(jì)算每個(gè)部門的員工數(shù):

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department;

結(jié)果:

示例-sum 按部門分組,計(jì)算每個(gè)部門的總薪水:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department;

結(jié)果:

示例-avg 按部門分組,計(jì)算每個(gè)部門的平均薪水:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT department, AVG(salary) AS average_salary
FROM employees
GROUP BY department;

結(jié)果:

示例-max-min 按部門分組,返回每個(gè)部門的最高和最低薪水:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, '銷售部' AS department, 5000 AS salary UNION ALL
    SELECT 2, '李四''市場(chǎng)部', 6000 UNION ALL
    SELECT 3, '王五''銷售部', 5500 UNION ALL
    SELECT 4, '趙六''技術(shù)部', 7000 UNION ALL
    SELECT 5, '孫七''市場(chǎng)部', 6500 UNION ALL
    SELECT 6, '周八''技術(shù)部', 7500 UNION ALL
    SELECT 7, '吳九''銷售部', 4500 UNION ALL
    SELECT 8, '鄭十''市場(chǎng)部', 5000 UNION ALL
    SELECT 9, '錢十一''技術(shù)部', 8000 UNION ALL
    SELECT 10, '王十二''銷售部', 4000
)
SELECT department, MAX(salary) AS max_salary, MIN(salary) AS min_salary
FROM employees
GROUP BY department;

結(jié)果:

3.4 總結(jié)

通過上述示例,你可以看到如何使用聚合函數(shù)和 GROUP BY 子句來(lái)對(duì)數(shù)據(jù)進(jìn)行分組和計(jì)算。這些示例涵蓋了 COUNT()、SUM()、AVG()、MAX() 和 MIN() 的基本用法,并結(jié)合 GROUP BY 進(jìn)行分組操作。

4. 多表操作

我們將詳細(xì)講解SQL中的多表操作,包括內(nèi)連接(INNER JOIN)、左連接(LEFT JOIN)、右連接(RIGHT JOIN)和全外連接(FULL OUTER JOIN)。我們將使用 WITH 子句創(chuàng)建兩個(gè)臨時(shí)表 employees 和 departments,然后進(jìn)行各種多表查詢。

4.1 使用 WITH 子句創(chuàng)建臨時(shí)表

首先,我們創(chuàng)建兩個(gè)臨時(shí)表 employees 和 departments。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部'
)

4.2 內(nèi)連接(INNER JOIN)

內(nèi)連接返回兩個(gè)表中滿足連接條件的所有行。

示例 要獲取每個(gè)員工及其所屬部門的名稱:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部'
)
SELECT e.name, d.department_name, e.salary
FROM employees e
INNER JOIN departments d ON e.department_id = d.id;

結(jié)果

4.3 左連接(LEFT JOIN)

左連接返回左表中的所有行,以及右表中滿足連接條件的行。如果右表中沒有匹配的行,則結(jié)果為 NULL。

示例 要獲取所有員工及其所屬部門的名稱,即使某些員工沒有部門:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000 UNION ALL
    SELECT 11, '無(wú)部門員工', NULL, 4000 -- 添加一個(gè)沒有部門的員工
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部'
)
SELECT e.name, d.department_name, e.salary
FROM employees e
LEFT JOIN departments d ON e.department_id = d.id;

結(jié)果

4.4 右連接(RIGHT JOIN)

右連接返回右表中的所有行,以及左表中滿足連接條件的行。如果左表中沒有匹配的行,則結(jié)果為 NULL。

示例 要獲取所有部門及其所屬員工的名稱,即使某些部門沒有員工:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部' UNION ALL
    SELECT 4, '人力資源部' -- 添加一個(gè)沒有員工的部門
)
SELECT e.name, d.department_name, e.salary
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.id;

結(jié)果

4.5 全外連接(FULL OUTER JOIN)

全外連接返回兩個(gè)表中的所有行,如果某個(gè)表中沒有匹配的行,則結(jié)果為 NULL。需要注意的是,并非所有數(shù)據(jù)庫(kù)系統(tǒng)都支持 FULL OUTER JOIN,例如 MySQL 不支持,但可以通過 UNION 實(shí)現(xiàn)類似效果。

示例 要獲取所有員工及其所屬部門的名稱,以及所有部門及其所屬員工的名稱,即使某些員工或部門沒有匹配:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部' UNION ALL
    SELECT 4, '人力資源部' -- 添加一個(gè)沒有員工的部門
)
SELECT e.name, d.department_name, e.salary
FROM employees e
FULL OUTER JOIN departments d ON e.department_id = d.id;

結(jié)果

4.6 總結(jié)

通過上述示例,你可以看到如何使用內(nèi)連接、左連接、右連接和全外連接來(lái)操作多個(gè)表。這些示例涵蓋了 INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL OUTER JOIN 的基本用法,并結(jié)合 WITH 子句創(chuàng)建臨時(shí)表進(jìn)行驗(yàn)證。

5. 高級(jí)特性

我們將詳細(xì)講解SQL中的高級(jí)特性,包括公用表表達(dá)式(CTE)、子查詢和窗口函數(shù)。我們將使用 WITH 子句創(chuàng)建臨時(shí)表 employees 和 departments,然后進(jìn)行各種高級(jí)查詢。

5.1 使用 WITH 子句創(chuàng)建臨時(shí)表

首先,我們創(chuàng)建兩個(gè)臨時(shí)表 employees 和 departments。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部'
)

5.2 公用表表達(dá)式(CTE)

公用表表達(dá)式(CTE)是一個(gè)臨時(shí)結(jié)果集,可以在查詢中多次引用。CTE 使用 WITH 子句定義。

示例 要計(jì)算每個(gè)部門的平均薪水,并使用 CTE 來(lái)簡(jiǎn)化查詢:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部'
),
department_avg_salary AS (--每個(gè)部門平均薪水
    SELECT department_id, AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department_id
)
SELECT d.department_name, das.avg_salary
FROM departments d
JOIN department_avg_salary das ON d.id = das.department_id;

結(jié)果

5.3 子查詢

子查詢是嵌套在另一個(gè)查詢中的查詢。子查詢可以出現(xiàn)在 SELECT、FROM、WHERE 子句中。

示例 要獲取薪水高于平均薪水的員工:

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

結(jié)果:

5.4 常用的窗口函數(shù)

窗口函數(shù)對(duì)一組行進(jìn)行計(jì)算,并返回每個(gè)行的計(jì)算結(jié)果。窗口函數(shù)通常與 OVER 子句一起使用。

ROW_NUMBER(),RANK() 和 DENSE_RANK()

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 4500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT 
   name, department_id, salary,
   ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_number,
   RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank_salary,
   DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank_salary
FROM employees

結(jié)果:

NTILE(2)

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 4500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT 
    name, department_id, salary,
    NTILE(2) OVER (PARTITION BY department_id ORDER BY salary DESC) AS ntile_2
FROM 
    employees;

結(jié)果:

LAG() 和 LEAD()

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 4500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT 
    name, department_id, salary,
    LAG(salary, 1, 0) OVER (PARTITION BY department_id ORDER BY salary) AS lag_salary,
    LEAD(salary, 1, 0) OVER (PARTITION BY department_id ORDER BY salary) AS lead_salary
FROM employees;

結(jié)果:

FIRST_VALUE() 和 LAST_VALUE()

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 4500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT 
    name, department_id, salary,
    FIRST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary) AS first_value_salary,
    LAST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary) AS last_value_salary
FROM employees;

結(jié)果

????注意: LAST_VALUE() 默認(rèn)情況下會(huì)在窗口內(nèi)逐行計(jì)算,如果需要在整個(gè)分區(qū)計(jì)算,可以使用 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 4500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT 
    name, department_id, salary,
    FIRST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary) AS first_value_salary,
    LAST_VALUE(salary) OVER (PARTITION BY department_id ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_value_salary
FROM employees;

結(jié)果:

常用聚合函數(shù)在窗口中的用法

聚合函數(shù)在窗口中的用法允許你在窗口內(nèi)進(jìn)行聚合計(jì)算,例如計(jì)算窗口內(nèi)的總和、平均值等。這通常使用 OVER 子句來(lái)定義窗口。

1. SUM() - 累積和

計(jì)算每個(gè)員工的累積薪水(按薪水降序排列)。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT 
    name, salary,
    SUM(salary) OVER (ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_salary
FROM 
    employees;

結(jié)果:

????在這個(gè)示例中,SUM(salary) OVER (ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 計(jì)算從第一個(gè)行到當(dāng)前行的累積薪水。

2. AVG() - 移動(dòng)平均

計(jì)算每個(gè)員工的移動(dòng)平均薪水(按薪水降序排列,窗口大小為3)。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT name, salary,
       AVG(salary) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_salary
FROM employees;

結(jié)果:

????在這個(gè)示例中,AVG(salary) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) 計(jì)算當(dāng)前行及其前兩行的平均薪水。

3. COUNT() - 窗口內(nèi)行數(shù)

計(jì)算每個(gè)員工的窗口內(nèi)行數(shù)(按薪水降序排列,窗口大小為3)。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT name, salary,
       COUNT(*) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS window_count
FROM employees;

結(jié)果:

????在這個(gè)示例中,COUNT(*) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) 計(jì)算當(dāng)前行及其前兩行的行數(shù)。

4. MAX() 和 MIN() - 窗口內(nèi)最大值和最小值

計(jì)算每個(gè)員工的窗口內(nèi)最大值和最小值(按薪水降序排列,窗口大小為3)。

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
)
SELECT name, salary,
       MAX(salary) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS max_salary,
       MIN(salary) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS min_salary
FROM employees;

結(jié)果:

????在這個(gè)示例中,MAX(salary) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) 和 MIN(salary) OVER (ORDER BY salary DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) 分別計(jì)算當(dāng)前行及其前兩行的最大值和最小值。

5.5 總結(jié)

通過上述示例,你可以看到如何使用 FIRST_VALUE() 和 LAST_VALUE() 窗口函數(shù)來(lái)獲取窗口內(nèi)的第一個(gè)和最后一個(gè)值,以及如何在窗口中使用聚合函數(shù)(如 SUM()、AVG()、COUNT()、MAX() 和 MIN())進(jìn)行復(fù)雜的計(jì)算。

6. 案例

下是三個(gè)綜合的SQL案例,涵蓋了我們之前學(xué)習(xí)的各種概念,包括數(shù)據(jù)檢索、聚合與分組、多表操作以及高級(jí)特性(如窗口函數(shù)和公用表表達(dá)式)。這些案例將幫助你更好地理解和應(yīng)用這些知識(shí)。

6.1 案例:?jiǎn)T工薪資分析

6.1.1 目標(biāo)

分析每個(gè)部門的員工薪資情況,包括平均薪資、最高薪資、最低薪資以及每個(gè)員工的薪資排名。

6.1.2 數(shù)據(jù)準(zhǔn)備

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部'
)

6.1.3 查詢

WITH employees AS (
    SELECT 1 AS id, '張三' AS name, 1 AS department_id, 5000 AS salary UNION ALL
    SELECT 2, '李四', 2, 6000 UNION ALL
    SELECT 3, '王五', 1, 5500 UNION ALL
    SELECT 4, '趙六', 3, 7000 UNION ALL
    SELECT 5, '孫七', 2, 6500 UNION ALL
    SELECT 6, '周八', 3, 7500 UNION ALL
    SELECT 7, '吳九', 1, 4500 UNION ALL
    SELECT 8, '鄭十', 2, 5000 UNION ALL
    SELECT 9, '錢十一', 3, 8000 UNION ALL
    SELECT 10, '王十二', 1, 4000
),
departments AS (
    SELECT 1 AS id, '銷售部' AS department_name UNION ALL
    SELECT 2, '市場(chǎng)部' UNION ALL
    SELECT 3, '技術(shù)部'
),
department_stats AS (
    SELECT department_id,
           AVG(salary) AS avg_salary,
           MAX(salary) AS max_salary,
           MIN(salary) AS min_salary
    FROM employees
    GROUP BY department_id
)
SELECT e.name,
       e.salary,
       d.department_name,
       ds.avg_salary,
       ds.max_salary,
       ds.min_salary,
       RANK() OVER (PARTITION BY e.department_id ORDER BY e.salary DESC) AS salary_rank
FROM employees e
JOIN departments d ON e.department_id = d.id
JOIN department_stats ds ON e.department_id = ds.department_id;

6.1.4 結(jié)果

6.2 案例:銷售數(shù)據(jù)分析

6.2.1 目標(biāo)

分析每個(gè)銷售員的銷售業(yè)績(jī),包括總銷售額、平均銷售額以及每個(gè)銷售員的排名。

6.2.2 數(shù)據(jù)準(zhǔn)備

WITH sales AS (
    SELECT 1 AS id, '張三' AS salesperson, 1000 AS amount UNION ALL
    SELECT 2, '李四', 1500 UNION ALL
    SELECT 3, '張三', 2000 UNION ALL
    SELECT 4, '李四', 2500 UNION ALL
    SELECT 5, '王五', 3000 UNION ALL
    SELECT 6, '王五', 3500 UNION ALL
    SELECT 7, '張三', 4000 UNION ALL
    SELECT 8, '李四', 4500 UNION ALL
    SELECT 9, '王五', 5000 UNION ALL
    SELECT 10, '張三', 5500
)

6.2.3 查詢

WITH sales AS (
    SELECT 1 AS id, '張三' AS salesperson, 1000 AS amount UNION ALL
    SELECT 2, '李四', 1500 UNION ALL
    SELECT 3, '張三', 2000 UNION ALL
    SELECT 4, '李四', 2500 UNION ALL
    SELECT 5, '王五', 3000 UNION ALL
    SELECT 6, '王五', 3500 UNION ALL
    SELECT 7, '張三', 4000 UNION ALL
    SELECT 8, '李四', 4500 UNION ALL
    SELECT 9, '王五', 5000 UNION ALL
    SELECT 10, '張三', 5500
),
sales_summary AS (
    SELECT salesperson,
           SUM(amount) AS total_sales,
           AVG(amount) AS avg_sales
    FROM sales
    GROUP BY salesperson
)
SELECT salesperson,
       total_sales,
       avg_sales,
       RANK() OVER (ORDER BY total_sales DESC) AS sales_rank
FROM sales_summary;

6.2.4 結(jié)果

6.3 案例:股票價(jià)格分析

6.3.1 目標(biāo)

分析股票價(jià)格的變化趨勢(shì),包括最高價(jià)、最低價(jià)以及每日價(jià)格變化。

6.3.2 數(shù)據(jù)準(zhǔn)備

WITH stock_prices AS (
    SELECT '2023-01-01' AS date, 100 AS open_price, 105 AS close_price UNION ALL
    SELECT '2023-01-02', 105, 110 UNION ALL
    SELECT '2023-01-03', 110, 108 UNION ALL
    SELECT '2023-01-04', 108, 112 UNION ALL
    SELECT '2023-01-05', 112, 115 UNION ALL
    SELECT '2023-01-06', 115, 113 UNION ALL
    SELECT '2023-01-07', 113, 118 UNION ALL
    SELECT '2023-01-08', 118, 120 UNION ALL
    SELECT '2023-01-09', 120, 119 UNION ALL
    SELECT '2023-01-10', 119, 122
)

6.3.3 查詢

WITH stock_prices AS (
    SELECT '2023-01-01' AS date, 100 AS open_price, 105 AS close_price UNION ALL
    SELECT '2023-01-02', 105, 110 UNION ALL
    SELECT '2023-01-03', 110, 108 UNION ALL
    SELECT '2023-01-04', 108, 112 UNION ALL
    SELECT '2023-01-05', 112, 115 UNION ALL
    SELECT '2023-01-06', 115, 113 UNION ALL
    SELECT '2023-01-07', 113, 118 UNION ALL
    SELECT '2023-01-08', 118, 120 UNION ALL
    SELECT '2023-01-09', 120, 119 UNION ALL
    SELECT '2023-01-10', 119, 122
),
daily_stats AS (
    SELECT date,
           close_price,
           LAG(close_price) OVER (ORDER BY date) AS prev_close_price,
           MAX(close_price) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS max_close_price,
           MIN(close_price) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS min_close_price
    FROM stock_prices
)
SELECT date,
       close_price,
       prev_close_price,
       max_close_price,
       min_close_price,
       close_price - prev_close_price AS price_change
FROM daily_stats;

6.3.4 結(jié)果

6.4 總結(jié)

通過這三個(gè)綜合案例,你可以看到如何將數(shù)據(jù)檢索、聚合與分組、多表操作以及高級(jí)特性(如窗口函數(shù)和公用表表達(dá)式)結(jié)合起來(lái),解決實(shí)際問題。這些案例涵蓋了從簡(jiǎn)單到復(fù)雜的查詢,幫助你更好地理解和應(yīng)用SQL知識(shí)。

抓住機(jī)遇,狠狠提升自己

隨著各行各業(yè)進(jìn)行數(shù)字化轉(zhuǎn)型,數(shù)據(jù)分析能力已經(jīng)成了職場(chǎng)的剛需能力,這也是這兩年CDA數(shù)據(jù)分析師大火的原因。和領(lǐng)導(dǎo)提建議再說“我感覺”“我覺得”,自己都覺得心虛,如果說“數(shù)據(jù)分析發(fā)現(xiàn)……”,肯定更有說服力。想在職場(chǎng)精進(jìn)一步還是要學(xué)習(xí)數(shù)據(jù)分析的,統(tǒng)計(jì)學(xué)、概率論、商業(yè)模型、SQL,Python還是要會(huì)一些,能讓你工作效率提升不少。備考CDA數(shù)據(jù)分析師的過程就是個(gè)自我提升的過程。

CDA 考試官方報(bào)名入口:https://www.cdaglobal.com/pinggu.html

數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請(qǐng)參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }