「前言」
"歡迎進(jìn)入SQL的奇妙世界,這是一種被數(shù)據(jù)分析師和數(shù)據(jù)科學(xué)家視為寶藏的編程語言。想象一下,有一天你醒來,發(fā)現(xiàn)自己被成堆的數(shù)據(jù)包圍。別擔(dān)心,SQL就像一根魔法棒,可以幫助你從這些混亂數(shù)據(jù)中抽絲剝繭。
使用SQL,你可以像魔術(shù)師一樣操作數(shù)據(jù),無論是過濾、排序、分組還是聚合數(shù)據(jù)。在這篇文章中,我們將介紹13個(gè)必備SQL語句,它們就像你的數(shù)據(jù)科學(xué)工具箱里的瑞士軍刀,簡單易學(xué),卻能幫你解決90%的數(shù)據(jù)任務(wù)問題。
無論你是SQL新手,還是已經(jīng)在數(shù)據(jù)海洋里暢游的老手,這篇文章都會(huì)像一盞燈塔,照亮你數(shù)據(jù)處理的道路。讓我們開始吧,一起揭開SQL的神秘面紗,發(fā)現(xiàn)其中的樂趣和實(shí)用技巧吧!"
. . .
1. 檢索(SELECT)
SELECT
語句用于從數(shù)據(jù)庫中的一個(gè)或多個(gè)表中檢索數(shù)據(jù)。您應(yīng)該掌握使用SELECT
來過濾、排序和分組數(shù)據(jù),使用不同的函數(shù),如WHERE
、ORDER BY
和GROUP BY
。語法:
SELECT column1, column2, column3FROM table_nameWHERE condition;
在這個(gè)例子中,column1、column2和column3是您想要從中檢索數(shù)據(jù)的列的名稱,table_name
是包含數(shù)據(jù)的表的名稱。WHERE
子句是可選的,用于指定查詢檢索數(shù)據(jù)必須滿足的條件。
示例:從顧客表中選擇客戶年齡大于或等于18歲的所有記錄
SELECT *FROM customersWHERE age >= 18;
. . .
2. 連接(JOIN)
JOIN
語句用于組合數(shù)據(jù)庫中兩個(gè)或多個(gè)表的數(shù)據(jù),作為數(shù)據(jù)分析師或數(shù)據(jù)科學(xué)家,掌握使用JOIN
從多個(gè)表中檢索數(shù)據(jù),是必備技能之一。常用的連接類型主要有內(nèi)連接、左連接、右連接以及外連接。
2.1 內(nèi)連接(INNER JOIN)
內(nèi)連接只返回兩張表中滿足連接條件且指定列的所有匹配行。例如下面的示例:
SELECT e.employee_name, d.department_nameFROM employees eINNER JOIN departments dON e.department_id = d.department_id;
在這個(gè)示例中,員工表(employees)和部門表(departments)使用department_id
列作為連接條件,結(jié)果集只返回兩個(gè)表中部門編號相同的員工姓名和部門名稱。
2.2 左連接(LEFT JOIN)
也叫左外連接(LEFT OUTER JOIN),它會(huì)返回左表的所有行和右表中的匹配行,如果右表中不滿足匹配條件,則結(jié)果中對應(yīng)列的行以NULL
填充。例如:
SELECT customers.customer_name, orders.order_idFROM customersLEFT JOIN ordersON customers.customer_id = orders.customer_id;
在這個(gè)例子中,顧客表(customers)是左表,訂單表(orders)是右表。使用customer_id
列作為連接條件。結(jié)果集將包括customers表中的所有行和orders表中的匹配行。如果orders表中沒有匹配項(xiàng),則order_id
列的值將以NULL
填充。
2.3 右連接(RIGHT JOIN)
也叫右外連接(RIGHT OUTER JOIN),與左連接剛好相反,右連接的結(jié)果集會(huì)返回右表的所有行和左表中的匹配行,如果左表中不滿足匹配條件,則結(jié)果中對應(yīng)列的行以NULL
填充。例如:
SELECT customers.customer_name, orders.order_idFROM customersRIGHT JOIN ordersON customers.customer_id = orders.customer_id;
在這個(gè)例子中,訂單表(orders)是左表,顧客表(customers)是右表。使用customer_id
列作為連接條件。結(jié)果集將包括orders表中的所有行和customers表中的匹配行。如果customers表中沒有匹配項(xiàng),則customer_name
列的值將以NULL
填充。
2.4 全連接(FULL JOIN)
也叫全外連接(FULL OUTER JOIN),其結(jié)果集會(huì)返回兩張表的所有行,包括非匹配行(以NULL
表示),相當(dāng)于兩個(gè)數(shù)據(jù)集的并集。例如:
SELECT e.employee_name, d.department_nameFROM employees eFULL OUTER JOIN departments dON e.department_id = d.department_id;
以上示例將返回所有員工和部門的信息,包括還未分配部門的新員工(部門名稱以NULL
表示)以及還沒有員工的新部門(員工姓名以NULL
表示)。
💡 值得注意的是,某些數(shù)據(jù)庫并不支持全連接(如MySQL),可用左連接、右連接加UNION (ALL)
實(shí)現(xiàn)全連接效果。
. . .
3. 過濾(WHERE)
WHERE
語句用于根據(jù)指定條件過濾數(shù)據(jù)。你應(yīng)該掌握使用WHERE
來檢索僅滿足特定條件的數(shù)據(jù)。
以下是在SQL中使用WHERE
語句過濾表中數(shù)據(jù)的示例:
假設(shè)我們有一個(gè)名為“employees”的表,其中包含name
(姓名)、department
(部門)和salary
(薪水)等列。我們可以使用WHERE
語句選擇那些在“Sales”(銷售)部門工作且薪水超過50,000美元的員工:
SELECT name, department, salaryFROM employeesWHERE department = 'Sales' AND salary > 50000;
這個(gè)查詢將返回所有在“Sales”(銷售)部門工作且薪水超過50,000美元的員工名單,查詢結(jié)果中會(huì)顯示他們的姓名、部門和薪水。
. . .
4. 分組(GROUP BY)
GROUP BY
語句用于根據(jù)一個(gè)或多個(gè)列對數(shù)據(jù)進(jìn)行分組,并且可以使用聚合函數(shù)(例如COUNT
、SUM
、AVG
)來計(jì)算分組數(shù)據(jù)的匯總。你應(yīng)該掌握使用GROUP BY
來按類別分析數(shù)據(jù)。
假設(shè)我們有一個(gè)名為“employees”的表,其中包含name
(姓名)、department
(部門)和salary
(薪水)等列。我們可以使用GROUP BY
語句按部門對員工進(jìn)行分組,并計(jì)算每個(gè)部門的平均薪水:
SELECT department, AVG(salary) as avg_salaryFROM employeesGROUP BY department;
這個(gè)查詢將返回所有部門及其平均薪水的列表,該平均薪水是通過計(jì)算該部門所有員工薪水之和然后除以該部門員工數(shù)得出的。GROUP BY
子句用于按部門對員工進(jìn)行分組,AVG
函數(shù)用于計(jì)算每個(gè)部門的平均薪水。
如果有需要,我們還可以按部門平均薪水降序輸出結(jié)果:
SELECT department, AVG(salary) as avg_salaryFROM employeesGROUP BY departmentORDER BY avg_salary DESC;
. . .
5. 過濾(HAVING)
這個(gè)過濾與WHERE
不同,HAVING
是用于對分組后的結(jié)果進(jìn)行過濾,它用在GROUP BY
子句之后,而WHERE
則是用于對分組前表中的單行數(shù)據(jù)進(jìn)行過濾。
以下是SQL中使用HAVING
子句的示例:
假設(shè)我們有一個(gè)名為“orders”的表,其中包含order_id
(訂單編號)、customer_id
(客戶編號)、product_id
(產(chǎn)品編號)和quantity
(數(shù)量)等列。我們想要找到下單的產(chǎn)品總數(shù)不低于50的客戶。我們可以使用GROUP BY
子句按客戶對訂單進(jìn)行分組,并計(jì)算每個(gè)客戶訂購的每種產(chǎn)品的總數(shù)量。然后使用HAVING
子句對結(jié)果進(jìn)行過濾,從而篩選出符合條件的客戶:
SELECT customer_id, SUM(quantity) AS total_quantityFROM ordersGROUP BY customer_idHAVING SUM(quantity) >= 50;
這個(gè)查詢將返回所有客戶及其訂購的產(chǎn)品總數(shù)量的列表,但只包括那些產(chǎn)品總數(shù)不低于50的客戶。GROUP BY
子句用于按客戶對訂單進(jìn)行分組,SUM
函數(shù)用于計(jì)算每個(gè)客戶訂購的產(chǎn)品總數(shù)量,HAVING
子句用于過濾結(jié)果,僅包括那些總共訂購產(chǎn)品總數(shù)不低于50的客戶。
. . .
6. 窗口函數(shù)
SQL中的窗口函數(shù)用于對與當(dāng)前行相關(guān)的一組行執(zhí)行計(jì)算。這些函數(shù)應(yīng)用于一個(gè)窗口,即根據(jù)指定條件或分區(qū)從表中選取的行的子集。以下是SQL中一些窗口函數(shù)的示例:
ROW_NUMBER()
:這個(gè)函數(shù)為分區(qū)內(nèi)的每一行分配一個(gè)唯一的連續(xù)編號(即連續(xù)不跳躍排名)。ROW_NUMBER()
函數(shù)的語法如下:
ROW_NUMBER() OVER ( [PARTITION BY partition_expression, ... ] ORDER BY sort_expression [ASC | DESC], ...)
- PARTITION BY:這是可選的。它將結(jié)果集劃分為多個(gè)分區(qū),然后對每個(gè)分區(qū)應(yīng)用
ROW_NUMBER
函數(shù)。如果不指定,函數(shù)會(huì)將整個(gè)結(jié)果集視為一個(gè)單一分區(qū)。 - ORDER BY:用于指定行號分配的順序。每個(gè)分區(qū)可以有不同的順序。
示例:
SELECT EmployeeID, Department, Salary, ROW_NUMBER() OVER ( PARTITION BY Department ORDER BY Salary DESC ) AS RowNumFROM Employees;
這個(gè)查詢將返回每個(gè)員工的編號、部門、薪水以及在部門內(nèi)的薪水排名(由高到低)。
SUM()
:用于計(jì)算分區(qū)內(nèi)某列的總和。語法如下:
SELECT column1, column2, ..., SUM(column3) OVER (PARTITION BY column1) AS column3_sumFROM table_name;
這個(gè)查詢將返回一個(gè)結(jié)果集,并帶有一個(gè)額外的列column3_sum
,該列包含基于column1
值的每個(gè)分區(qū)中column3
的總和。
RANK()
:這個(gè)函數(shù)根據(jù)指定列的值為分區(qū)內(nèi)的每一行分配一個(gè)排名(允許同名并列,且會(huì)跳過同名次所占用的序號,因此也稱為連續(xù)跳躍式排名)。語法如下:
SELECT column1, column2, ..., RANK() OVER (PARTITION BY column1 ORDER BY column3 DESC) AS rank_numFROM table_name;
這個(gè)查詢將返回一個(gè)結(jié)果集,并帶有一個(gè)額外的列rank_num
,該列包含基于column3
降序排列的每個(gè)分區(qū)內(nèi)每一行的排名。
AVG()
:這個(gè)函數(shù)計(jì)算分區(qū)內(nèi)某列的平均值。語法如下:
SELECT column1, column2, ..., AVG(column3) OVER (PARTITION BY column1) AS column3_avgFROM table_name;
這個(gè)查詢將返回一個(gè)結(jié)果集,并帶有一個(gè)額外的列column3_avg
,該列包含基于column1
值的每個(gè)分區(qū)中column3
的平均值。
💡請注意,窗口函數(shù)的語法可能會(huì)根據(jù)使用的具體數(shù)據(jù)庫管理系統(tǒng)(DBMS)而有所不同。
. . .
7. 組合(UNION)
在SQL中,UNION
運(yùn)算符用于將兩個(gè)或多個(gè)SELECT
語句的結(jié)果組合成一個(gè)結(jié)果集。SELECT
語句必須有相同數(shù)量的列,且列必須具有兼容的數(shù)據(jù)類型。結(jié)果集中的重復(fù)行會(huì)自動(dòng)被移除(如果想要包含重復(fù)行,請使用UNION ALL
)。
以下是在SQL中使用UNION
運(yùn)算符的示例:
假設(shè)我們有兩個(gè)表“customers”(客戶)和“employees”(員工),它們都包含name
(姓名)和city
(城市)列。我們想創(chuàng)建一個(gè)名單,列出所有住在紐約市的人(包括客戶和員工)。這里就可以使用UNION
運(yùn)算符來組合兩個(gè)SELECT
語句的結(jié)果:
SELECT name, cityFROM customersWHERE city = 'New York'UNIONSELECT name, cityFROM employeesWHERE city = 'New York';
這個(gè)查詢將返回所有住在紐約市的人的名單,包括客戶和員工。第一個(gè)SELECT
語句檢索所有住在紐約市的客戶,而第二個(gè)SELECT
語句檢索所有住在紐約市的員工。UNION
運(yùn)算符結(jié)合這兩個(gè)SELECT
語句的結(jié)果,并移除重復(fù)行。
Tips:如果允許包含重復(fù)行,且查詢表數(shù)據(jù)量較大的情況下,可以使用UNION ALL
提升查詢性能,因?yàn)?code style="margin: 0px 2px; padding: 2px 4px; outline: 0px; user-select: initial !important; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(244, 86, 157); line-height: 1.8em; letter-spacing: 0em; background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(244, 86, 157, 0.1); width: auto; height: auto; border-style: none; border-width: 3px; border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4); border-radius: 4px; font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace; word-break: break-all;">UNION要排除重復(fù)行會(huì)涉及排序操作。
. . .
8. 創(chuàng)建(CREATE)
CREATE
語句用于創(chuàng)建新的數(shù)據(jù)庫表、視圖或其他數(shù)據(jù)庫對象。以下是在SQL中使用CREATE
語句的示例:
假設(shè)我們想要?jiǎng)?chuàng)建一個(gè)名為“customers”的新表,其中包含id
(編號)、name
(姓名)、email
(電子郵件)和phone
(電話)等列。我們可以使用CREATE
語句來實(shí)現(xiàn)這一點(diǎn):
CREATE TABLE customers ( id INT PRIMARY KEY, name VARCHAR(50), email VARCHAR(100), phone VARCHAR(20));
這個(gè)查詢將創(chuàng)建一個(gè)名為“customers”的新表,包含四列:“id”(編號)、“name”(姓名)、“email”(電子郵件)和“phone”(電話)。其中,“id”列被定義為整數(shù)類型,并設(shè)置為表的主鍵?!皀ame”列被定義為最大長度為50個(gè)字符的字符串,而“email”和“phone”列也被定義為字符串,其最大長度分別為100和20個(gè)字符。
在執(zhí)行這個(gè)查詢之后,我們可以對“customers”表進(jìn)行常規(guī)的增(INSERT
)、刪(DELETE
)、改(UPDATE
)、查(SELECT
)操作。比如,添加向表中添加數(shù)據(jù)并檢索它們:
INSERT INTO customers (id, name, email, phone)VALUES (1, 'Jack Zhang', 'jackzhang@example.com', '18888888888');
SELECT * FROM customers;
這個(gè)查詢將向“customers”表中插入一行新數(shù)據(jù),包括編號為1、姓名為“Jack Zhang”、電子郵件為“jackzhang@example.com”和電話號碼為“18888888888”。第二個(gè)查詢將從“customers”表中檢索所有行,其中包括我們剛剛插入的新行:
id | name | email | phone--------------------------------------------1 | Jack Zhang | jackzhang@example.com | 18888888888
在這個(gè)例子中,我們使用CREATE
語句在數(shù)據(jù)庫中創(chuàng)建了一個(gè)新表,并向該表中插入了一行新數(shù)據(jù)。
. . .
9. 插入(INSERT)
INSERT
語句用于向數(shù)據(jù)庫表中插入數(shù)據(jù)。以下是在SQL中使用INSERT
語句的示例:
假設(shè)我們有一個(gè)名為“students”的表,其中包含id
(編號)、name
(姓名)、major
(專業(yè))和gpa
(績點(diǎn)平均值)等列。我們想要為一位編號為1234、姓名為“Jack Zhang”、專業(yè)為“Software Engineering”(軟件工程)、績點(diǎn)為3.5的學(xué)生在表中插入一行新數(shù)據(jù)??梢允褂?code style="margin: 0px 2px; padding: 2px 4px; outline: 0px; user-select: initial !important; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(244, 86, 157); line-height: 1.8em; letter-spacing: 0em; background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(244, 86, 157, 0.1); width: auto; height: auto; border-style: none; border-width: 3px; border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4); border-radius: 4px; font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace; word-break: break-all;">INSERT語句來實(shí)現(xiàn)這一點(diǎn):
INSERT INTO students (id, name, major, gpa)VALUES (1234, 'Jack Zhang', 'Software Engineering', 3.5);
這個(gè)查詢將向“students”表中插入一行新數(shù)據(jù),并為id
(編號)、name
(姓名)、major
(專業(yè))和gpa
(績點(diǎn)平均值)列指定了相應(yīng)的值。INSERT
語句首先指定我們要插入數(shù)據(jù)的表的名稱,然后列出我們想要插入值的列。接著我們使用VALUES
關(guān)鍵字來指定我們想要插入到每一列中的值,按照列出的順序。
在執(zhí)行這個(gè)查詢之后,“students”表將包含一行新數(shù)據(jù),其值如下:
id | name | major | gpa-----------------------------------------1234 | Jack Zhang | Software Engineering | 3.5
在這個(gè)示例中,我們使用INSERT
語句向?qū)W生表中插入了一條新數(shù)據(jù)。
. . .
10. 更新(UPDATE)
UPDATE
語句用于修改數(shù)據(jù)庫表中現(xiàn)有的數(shù)據(jù)。以下是在SQL中使用UPDATE
語句的示例:
假設(shè)我們有一個(gè)名為“students”的表,其中包含id
(編號)、name
(姓名)、major
(專業(yè))和gpa
(績點(diǎn)平均值)等列。我們想要更新編號為1234的學(xué)生的專業(yè)和績點(diǎn)??梢允褂?code style="margin: 0px 2px; padding: 2px 4px; outline: 0px; user-select: initial !important; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(244, 86, 157); line-height: 1.8em; letter-spacing: 0em; background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(244, 86, 157, 0.1); width: auto; height: auto; border-style: none; border-width: 3px; border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4); border-radius: 4px; font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace; word-break: break-all;">UPDATE語句來實(shí)現(xiàn)這一點(diǎn):
UPDATE studentsSET major = 'Computer Science', gpa = 3.7WHERE id = 1234;
這個(gè)查詢將更新“students”表中編號為1234的行的major
(專業(yè))和gpa
(績點(diǎn)平均值)列。UPDATE
語句首先指定我們想要更新的表的名稱,接著是SET
關(guān)鍵字和我們想要更新的列-值對列表。然后我們使用WHERE
子句來指定我們想要更新的行。在這個(gè)案例中,我們想要更新編號為1234的行,所以我們指定WHERE id = 1234
。
在執(zhí)行這個(gè)查詢之后,“students”表中編號為1234的行的major
和gpa
列將會(huì)被更新為新的值:
id | name | major | gpa--------------------------------------1234 | John Doe | Computer Science | 3.7
. . .
11. 刪除(DELETE)記錄
DELETE
語句用于從數(shù)據(jù)庫表中刪除一個(gè)或多個(gè)行。以下是在SQL中使用DELETE
語句的示例:
假設(shè)我們有一個(gè)名為“students”的表,其中包含id
(編號)、name
(姓名)、major
(專業(yè))和gpa
(績點(diǎn)平均值)等列。我們想要從表中刪除編號為1234的學(xué)生??梢允褂?code style="margin: 0px 2px; padding: 2px 4px; outline: 0px; user-select: initial !important; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(244, 86, 157); line-height: 1.8em; letter-spacing: 0em; background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(244, 86, 157, 0.1); width: auto; height: auto; border-style: none; border-width: 3px; border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4); border-radius: 4px; font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace; word-break: break-all;">DELETE語句來實(shí)現(xiàn)這一點(diǎn):
DELETE FROM studentsWHERE id = 1234;
這個(gè)查詢將從“students”表中移除編號為1234的行。DELETE
語句首先指定我們想要從中刪除數(shù)據(jù)的表的名稱,接著使用WHERE
子句來指定我們想要?jiǎng)h除的行。在這個(gè)案例中,我們想要?jiǎng)h除編號為1234的行,所以我們指定WHERE id = 1234
。
在執(zhí)行這個(gè)查詢之后,“students”表將不再包含編號為1234的行。
. . .
12. 刪除(DROP)數(shù)據(jù)庫對象
DROP
語句用于刪除數(shù)據(jù)庫表或其他數(shù)據(jù)庫對象。DROP
語句的語法根據(jù)被刪除對象的類型而有所不同,以下是一些常見的例子:
- DROP TABLE:這個(gè)語句用于刪除現(xiàn)有的表及其所有數(shù)據(jù)和索引。語法如下:
DROP TABLE table_name;
- DROP INDEX:這個(gè)語句用于從表中刪除現(xiàn)有的索引。語法如下:
DROP INDEX index_name ON table_name;
- DROP VIEW:這個(gè)語句用于刪除現(xiàn)有的視圖。語法如下:
DROP VIEW view_name;
- DROP PROCEDURE:這個(gè)語句用于刪除現(xiàn)有的存儲過程。語法如下:
DROP PROCEDURE procedure_name;
💡請注意,DROP
語句的確切語法可能會(huì)根據(jù)所使用的具體數(shù)據(jù)庫管理系統(tǒng)(DBMS)而有所不同。此外,在使用DROP
語句時(shí)要小心,因?yàn)樗鼤?huì)永久刪除指定的對象及其所有相關(guān)數(shù)據(jù)和索引。因此,在使用DROP
語句之前,請確保備份您的數(shù)據(jù)。
. . .
13. 修改(ALTER)
ALTER
語句用于修改數(shù)據(jù)庫表或其他數(shù)據(jù)庫對象的結(jié)構(gòu)。你應(yīng)該掌握使用ALTER
語句來添加或移除列、更改數(shù)據(jù)類型或修改表的其他方面。ALTER
語句的語法根據(jù)被修改對象的類型而有所不同,以下是一些常見的例子:
- ALTER TABLE:這個(gè)語句用于修改現(xiàn)有表的結(jié)構(gòu),比如添加或刪除列、更改數(shù)據(jù)類型或設(shè)置約束。語法如下:
ALTER TABLE table_nameADD column_name data_type [constraint],MODIFY column_name data_type [constraint],DROP column_name,ADD CONSTRAINT constraint_name constraint_definition,DROP CONSTRAINT constraint_name;
- ALTER INDEX:這個(gè)語句用于修改現(xiàn)有索引的結(jié)構(gòu),例如添加或移除列或更改索引類型。語法如下:
ALTER INDEX index_nameADD column_name,DROP column_name;
- ALTER VIEW:這個(gè)語句用于修改現(xiàn)有視圖的定義,例如更改用于創(chuàng)建視圖的
SELECT
語句。語法如下:
ALTER VIEW view_nameAS select_statement;
請注意,ALTER
語句的確切語法可能會(huì)根據(jù)所使用的具體數(shù)據(jù)庫管理系統(tǒng)(DBMS)而有所不同。
該文章在 2024/1/22 12:05:38 編輯過