1. SQL语言
SQL 即结构化查询语言(Structured Query Language),它是一种用于管理和操作关系型数据库的标准语言。借助 SQL,你能够对数据库中的数据进行创建、读取、更新和删除等操作。
用途
- 数据定义:SQL 可以定义数据库的结构,比如创建、修改和删除数据库、表、视图等对象。
- 数据操作:可以对数据库中的数据进行插入、更新和删除等操作。
- 数据查询:能从数据库中检索满足特定条件的数据。
- 数据控制:可以控制用户对数据库的访问权限,确保数据的安全性。
SQL中的关键字不区分大小写,为了保证 SQL 代码的规范性、可读性和可移植性,建议在每条 SQL 语句后面都加上分号。
一些最重要的 SQL 命令
SELECT- 从数据库中提取数据UPDATE- 更新数据库中的数据DELETE- 从数据库中删除数据INSERT INTO- 将新数据插入数据库CREATE DATABASE- 创建一个新数据库ALTER DATABASE- 修改数据库CREATE TABLE- 创建一个新表ALTER TABLE- 修改表DROP TABLE- 删除表CREATE INDEX- 创建索引(搜索键)DROP INDEX- 删除索引
1. SELECT 语句
SELECT语句
MySQL 的 SELECT 语句用于从数据库中选择数据。返回的数据存储在一个结果表中,称为结果集。
语法:
SELECT column1, column2, ...
FROM table_name;
column1, column2, ... 是您想要从中选择数据的表的字段名。如果您想要选择表中所有可用的字段,请使用以下语法:
SELECT * FROM table_name;
SELECT DISTINCT语句
SELECT DISTINCT 语句用于仅返回不同的值。
在表中,一列通常包含许多重复值;有时您只希望列出不同的值。
语法:
SELECT DISTINCT column1, column2, ...
FROM table_name;
2. WHERE 子句
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | Mexico City | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexico City | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
MySQL 中的 WHERE 子句用于筛选记录。它用于仅提取满足指定条件的记录。
语法:
SELECT column1, column2, ...
FROM table_name
WHERE condition;
注意: WHERE 子句不仅用于 SELECT 语句,还用于 UPDATE, DELETE 等语句!
示例:
SELECT * FROM Customers
WHERE Country = 'Mexico';
这条WHERE语句将选择所有来自“墨西哥”的客户信息。
SQL 要求在文本值周围加上单引号(大多数数据库系统也允许使用双引号)。但是,数值字段不应该用引号括起来。
示例:
SELECT * FROM Customers
WHERE CustomerID = 1;
-
WHERE 子句中的运算符
-
比较运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
= |
等于 | SELECT * FROM Customers WHERE Country = 'Germany'; |
!= 或 <> |
不等于 | SELECT * FROM Customers WHERE Country != 'USA'; |
> |
大于 | SELECT * FROM Products WHERE Price > 50; |
< |
小于 | SELECT * FROM Orders WHERE OrderDate < '2023-01-01'; |
>= |
大于等于 | SELECT * FROM Employees WHERE Salary >= 5000; |
<= |
小于等于 | SELECT * FROM Products WHERE Quantity <= 10; |
- 逻辑运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
AND |
逻辑与,所有条件都为真时结果才为真 | SELECT * FROM Customers WHERE Country = 'UK' AND City = 'London'; |
OR |
逻辑或,只要有一个条件为真结果就为真 | SELECT * FROM Customers WHERE Country = 'USA' OR Country = 'Canada'; |
NOT |
逻辑非,对条件结果取反 | SELECT * FROM Customers WHERE NOT Country = 'France'; |
- 范围运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
BETWEEN |
用于选取介于两个值之间的数据范围 | SELECT * FROM Products WHERE Price BETWEEN 10 AND 50; |
NOT BETWEEN |
用于选取不在两个值之间的数据范围 | SELECT * FROM Products WHERE Price NOT BETWEEN 10 AND 50; |
- 成员运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
IN |
判断某个值是否在指定的列表中 | SELECT * FROM Customers WHERE Country IN ('UK', 'USA', 'Canada'); |
NOT IN |
判断某个值是否不在指定的列表中 | SELECT * FROM Customers WHERE Country NOT IN ('UK', 'USA', 'Canada'); |
- 模式匹配运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
LIKE |
用于模糊匹配字符串 | SELECT * FROM Customers WHERE CustomerName LIKE 'A%';(以 A 开头的客户名) |
NOT LIKE |
用于不匹配指定模式的字符串 | SELECT * FROM Customers WHERE CustomerName NOT LIKE '%Ltd.%';(客户名中不包含 Ltd. 的记录) |
- 空值运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
IS NULL |
判断某个字段是否为空值 | SELECT * FROM Employees WHERE ManagerID IS NULL; |
IS NOT NULL |
判断某个字段是否不为空值 | SELECT * FROM Employees WHERE ManagerID IS NOT NULL; |
3. ORDER BY 关键字
MySQL 的 ORDER BY 关键字用于按升序或降序对结果集进行排序。
ORDER BY 关键字默认按升序对记录进行排序。要按降序对记录进行排序,请使用 DESC 关键字。
语法:
SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC|DESC;
演示数据库:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
以下 SQL 语句从“Customers”表中选择所有客户,并按“Country”列排序:
SELECT * FROM Customers
ORDER BY Country;
以下 SQL 语句从“Customers”表中选择所有客户,并按“Country”列降序排序:
SELECT * FROM Customers
ORDER BY Country DESC;
ORDER BY 多个列示例
以下 SQL 语句从“Customers”表中选择所有客户,并按“Country”和“CustomerName”列排序。这意味着它按 Country 排序,但如果某些行具有相同的 Country,则按 CustomerName 排序
SELECT * FROM Customers
ORDER BY Country, CustomerName;
4. INSERT INTO 语句
MySQL INSERT INTO 语句用于在表中插入新记录。
语法:
可以使用两种方式编写 INSERT INTO 语句
- 指定要插入的列名和值
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
- 如果要为表的所有列添加值,则无需在 SQL 查询中指定列名。但是,请确保值的顺序与表中的列顺序相同。在这种情况下,
INSERT INTO语法如下
INSERT INTO table_name
VALUES (value1, value2, value3, ...);
演示数据库:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 89 | White Clover Markets | Karl Jablonski | 305 - 14th Ave. S. Suite 3B | Seattle | 98128 | USA |
| 90 | Wilman Kala | Matti Karttunen | Keskuskatu 45 | Helsinki | 21240 | Finland |
| 91 | Wolski | Zbyszek | ul. Filtrowa 68 | Walla | 01-012 | Poland |
示例:
INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country)
VALUES ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway');
结果:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 89 | White Clover Markets | Karl Jablonski | 305 - 14th Ave. S. Suite 3B | Seattle | 98128 | USA |
| 90 | Wilman Kala | Matti Karttunen | Keskuskatu 45 | Helsinki | 21240 | Finland |
| 91 | Wolski | Zbyszek | ul. Filtrowa 68 | Walla | 01-012 | Poland |
| 92 | Cardinal | Tom B. Erichsen | Skagen 21 | Stavanger | 4006 | Norway |
我们可以注意到,在插入数据时并没有添加CustomerID字段的数据,但是CustomerID 列是一个自动递增字段,将在向表中插入新记录时自动生成。
仅在指定列中插入数据:
示例:
INSERT INTO Customers (CustomerName, City, Country)
VALUES ('Cardinal', 'Stavanger', 'Norway');
结果:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 89 | White Clover Markets | Karl Jablonski | 305 - 14th Ave. S. Suite 3B | Seattle | 98128 | USA |
| 90 | Wilman Kala | Matti Karttunen | Keskuskatu 45 | Helsinki | 21240 | Finland |
| 91 | Wolski | Zbyszek | ul. Filtrowa 68 | Walla | 01-012 | Poland |
| 92 | Cardinal | null | null | Stavanger | null | Norway |
未指定列的数据为空值null
5. 空值 NULL
空值字段是指没有值的字段。
如果表中的某个字段是可选的,则可以插入新记录或更新记录,而无需向该字段添加值。然后,该字段将保存为空值。
可以使用IS NULL 和 IS NOT NULL 运算符来测试空值。
示例:
SELECT column_names
FROM table_name
WHERE column_name IS NULL;
SELECT column_names
FROM table_name
WHERE column_name IS NOT NULL;
演示数据库:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | Mexico City | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexico City | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
以下 SQL 列出了所有在 "Address" 字段中具有 NULL 值的客户
SELECT CustomerName, ContactName, Address
FROM Customers
WHERE Address IS NULL;
查询结果为0,没有含空值的用户信息。
以下 SQL 列出了所有在 "Address" 字段中具有值的客户
SELECT CustomerName, ContactName, Address
FROM Customers
WHERE Address IS NOT NULL;
结果是整个信息表,都不含有空值。
6. UPDATE语句
UPDATE 语句用于修改表中现有的记录。
语法:
UPDATE 表名
SET 列1 = 值1, 列2 = 值2, ...
WHERE 条件;
注意:在更新表中的记录时要注意 WHERE 语句中的子句。 WHERE 子句指定应更新的记录。如果省略 WHERE 子句,则将更新表中的所有记录!
演示数据库:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | Mexico City | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexico City | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
以下 SQL 语句将更新第一个客户 (CustomerID = 1) 的新的联系人 和 新的城市。
UPDATE Customers
SET ContactName = 'Alfred Schmidt', City = 'Frankfurt'
WHERE CustomerID = 1;
结果:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 1 | Alfred Schmidt | Alfred Schmidt | Obere Str. 57 | Frankfurt | 12209 | Germany |
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | Mexico City | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexico City | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
更新多条记录:
是 WHERE 子句决定了要更新多少条记录。
以下 SQL 语句将把所有国家为“墨西哥”的记录的 PostalCode 更新为 00000
UPDATE Customers
SET PostalCode = 00000
WHERE Country = 'Mexico';
注意:在更新记录时如果省略了WHERE子句将会更新所有记录
7. DELETE 语句
MySQL DELETE 语句用于删除表中的现有记录。
语法:
DELETE FROM table_name WHERE condition;
注意: 删除表中的记录时要小心!请注意 DELETE 语句中的 WHERE 子句。 WHERE 子句指定要删除的记录。如果省略 WHERE 子句,则将删除表中的所有记录!
演示数据库
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
以下 SQL 语句会从 "Customers" 表中删除客户 "Alfreds Futterkiste"
DELETE FROM Customers WHERE CustomerName='Alfreds Futterkiste';
结果:
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
删除所有记录
可以在不删除表的情况下删除表中的所有行。这意味着表结构、属性和索引将保持完整
DELETE FROM table_name;
以下 SQL 语句将删除 "Customers" 表中的所有行,但不删除表本身
DELETE FROM Customers;
8. LIMMIT 子句
LIMIT 子句用于指定要返回的记录行数。 LIMIT 子句在具有数千条记录的大型表格上很有用。返回大量记录会影响性能。
语法:
SELECT column_name(s)
FROM table_name
WHERE condition
LIMIT number;
演示数据库
以下是 Northwind 示例数据库中“Customers”表格的选择
| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
|---|---|---|---|---|---|---|
| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
| 2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
以下 SQL 语句从“Customers”表格中选择前三条记录
SELECT * FROM Customers
LIMIT 3;
如果我们想选择记录 4 到 6(含)怎么办?
MySQL 提供了一种处理此问题的方法:使用 OFFSET,表示从头开始跳过的行数。
下面的 SQL 查询表示“仅返回 3 条记录,从记录 4 开始(OFFSET 3)”
SELECT * FROM Customers
LIMIT 3 OFFSET 3;
以下 SQL 语句添加了WHERE子句,从“Customers”表格中选择前三条记录,其中国家为“Germany”
SELECT * FROM Customers
WHERE Country='Germany'
LIMIT 3;
9. MIN() 和 MAX() 函数
MIN() 函数返回所选列的最小值。MAX() 函数返回所选列的最大值。
MIN() 语法
SELECT MIN(*column_name*)
FROM *table_name*
WHERE *condition*;
MAX() 语法
SELECT MAX(*column_name*)
FROM *table_name*
WHERE *condition*;
演示数据库:
| ProductID | ProductName | SupplierID | CategoryID | Unit | Price |
|---|---|---|---|---|---|
| 1 | Chais | 1 | 1 | 10 boxes x 20 bags | 18 |
| 2 | Chang | 1 | 1 | 24 - 12 oz bottles | 19 |
| 3 | Aniseed Syrup | 1 | 2 | 12 - 550 ml bottles | 10 |
| 4 | Chef Anton's Cajun Seasoning | 2 | 2 | 48 - 6 oz cans | 22 |
| 5 | Chef Anton's Gumbo Mix | 2 | 2 | 36 boxes | 21.35 |
以下 SQL 语句用于查找最便宜产品的价格
SELECT MIN(Price) AS SmallestPrice
FROM Products;
AS 是 SQL 里用来给查询结果列取别名的关键字。这里将 MIN(Price) 的结果列命名为 SmallestPrice,这样在查询结果中,该列就会以 SmallestPrice 显示。
以下 SQL 语句用于查找最昂贵产品的价格
SELECT MAX(Price) AS LargestPrice
FROM Products;
10. COUNT()、AVG() 、 SUM() 函数
COUNT() 函数返回匹配指定条件的行数。
COUNT() 语法
SELECT COUNT(*column_name*)
FROM *table_name*
WHERE *condition*;
AVG() 函数返回数值列的平均值。
AVG() 语法
SELECT AVG(*column_name*)
FROM *table_name*
WHERE *condition*;
SUM() 函数返回数值列的总和。
SUM() 语法
SELECT SUM(*column_name*)
FROM *table_name*
WHERE *condition*;
11. LIKE 运算符
在 WHERE 子句中使用 LIKE 运算符,在列中搜索指定模式。
通常与 LIKE 运算符结合使用两个通配符
- 百分号 (%) 代表零个、一个或多个字符
- 下划线符号 (_) 代表单个字符
百分号和下划线也可以组合使用!
语法:
SELECT column1, column2, ...
FROM table_name
WHERE column_name LIKE pattern;
这里的 column1, column2, ... 是要查询的列名,table_name 是要查询的表名,column_name 是用于进行模糊匹配的列,pattern 是匹配模式。
以下是一些使用 '%' 和 '_' 通配符的示例,它们展示了不同的 LIKE 运算符
| LIKE 运算符 | 描述 |
|---|---|
| WHERE CustomerName LIKE 'a%' | 查找以 "a" 开头的任何值 |
| WHERE CustomerName LIKE '%a' | 查找以 "a" 结尾的任何值 |
| WHERE CustomerName LIKE '%or%' | 查找在任何位置包含 "or" 的任何值 |
| WHERE CustomerName LIKE '_r%' | 查找在第二个位置包含 "r" 的任何值 |
| WHERE CustomerName LIKE 'a_%' | 查找以 "a" 开头且至少包含两个字符的任何值 |
| WHERE CustomerName LIKE 'a__%' | 查找以 "a" 开头且至少包含三个字符的任何值 |
| WHERE ContactName LIKE 'a%o' | 查找以 "a" 开头并以 "o" 结尾的任何值 |
12. 通配符
通配符用于替换字符串中的一个或多个字符。
通配符与 LIKE 运算符一起使用。 LIKE 运算符用于 WHERE 子句中,以在列中搜索指定模式。
MySQL 中的通配符
| 符号 | 描述 | 示例 |
|---|---|---|
| % | 表示零个或多个字符 | bl% 查找 bl、black、blue 和 blob |
| _ | 表示单个字符 | h_t 查找 hot、hat 和 hit |
通配符也可以组合使用!
13. IN
MySQL 的 IN 运算符允许在 WHERE 子句中指定多个值。
IN 运算符是多个 OR 条件的简写。
语法
SELECT *column_name(s)*
FROM *table_name*
WHERE *column_name* IN (*value1*, *value2*, ...);
或
SELECT *column_name(s)*
FROM *table_name*
WHERE *column_name* IN (*SELECT STATEMENT*);
以下 SQL 语句选择所有位于“德国”、“法国”或“英国”的客户
SELECT * FROM Customers
WHERE Country IN ('Germany', 'France', 'UK');
以下 SQL 语句选择所有不在“德国”、“法国”或“英国”的客户
SELECT * FROM Customers
WHERE Country NOT IN ('Germany', 'France', 'UK');
以下 SQL 语句选择所有来自与供应商相同国家的客户
SELECT * FROM Customers
WHERE Country IN (SELECT Country FROM Suppliers);
14. BETWEEN 运算符
MySQL BETWEEN 运算符用于选择给定范围内的值。这些值可以是数字、文本或日期。
BETWEEN 运算符是包含性的:开头和结尾值都包含在内。
语法
SELECT column_name(s)
FROM table_name
WHERE column_name BETWEEN value1 AND value2;
以下 SQL 语句选择价格在 10 到 20 之间的所有产品
SELECT * FROM Products
WHERE Price BETWEEN 10 AND 20;
要显示不在上一个示例范围内的产品,请使用 NOT BETWEEN
SELECT * FROM Products
WHERE Price NOT BETWEEN 10 AND 20;
以下 SQL 语句选择价格在 10 到 20 之间的所有产品。此外,不显示 CategoryID 为 1、2 或 3 的产品
SELECT * FROM Products
WHERE Price BETWEEN 10 AND 20
AND CategoryID NOT IN (1,2,3);
以下 SQL 语句选择 ProductName 在 "Carnarvon Tigers" 和 "Mozzarella di Giovanni" 之间的所有产品
SELECT * FROM Products
WHERE ProductName BETWEEN 'Carnarvon Tigers' AND 'Mozzarella di Giovanni'
ORDER BY ProductName;
以下 SQL 语句选择 OrderDate 在 '01-July-1996' 和 '31-July-1996' 之间的所有订单
SELECT * FROM Orders
WHERE OrderDate BETWEEN '1996-07-01' AND '1996-07-31';
15. 别名AS
别名用于为表或表中的列赋予一个临时名称。别名通常用于使列名更易读。别名只在该查询持续期间存在。
别名是使用 AS 关键字创建的。
别名列语法
SELECT column_name AS alias_name
FROM table_name;
别名表语法
SELECT column_name(s)
FROM table_name AS alias_name;
16. 连接 JOIN
一个 JOIN 语句用于根据两个或多个表格之间相关的列组合两个或多个表格中的行。
内连接(INNER JOIN)
内连接返回的是两个表中匹配的行。只有当连接条件满足时,对应的行才会出现在结果集中。
语法
SELECT column1, column2, ...
FROM table1
INNER JOIN table2
ON table1.column = table2.column;
示例
假设存在 orders 表和 customers 表,orders 表包含 order_id、customer_id 和 order_date 列,customers 表包含 customer_id 和 customer_name 列。要查询每个订单对应的客户姓名,可以使用内连接:
SELECT orders.order_id, customers.customer_name, orders.order_date
FROM orders
INNER JOIN customers
ON orders.customer_id = customers.customer_id;
左连接(LEFT JOIN 或 LEFT OUTER JOIN)
左连接返回左表中的所有行,以及右表中匹配的行。若右表中没有匹配的行,则右表的列值为 NULL。
语法
SELECT column1, column2, ...
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;
示例
SELECT customers.customer_name, orders.order_id
FROM customers
LEFT JOIN orders
ON customers.customer_id = orders.customer_id;
这个查询会返回所有客户的信息,以及他们对应的订单信息。若某个客户没有订单,order_id 列的值将为 NULL。
右连接(RIGHT JOIN 或 RIGHT OUTER JOIN)
右连接和左连接相反,它返回右表中的所有行,以及左表中匹配的行。若左表中没有匹配的行,则左表的列值为 NULL。
语法
SELECT column1, column2, ...
FROM table1
RIGHT JOIN table2
ON table1.column = table2.column;
示例
SELECT customers.customer_name, orders.order_id
FROM customers
RIGHT JOIN orders
ON customers.customer_id = orders.customer_id;
全连接(FULL JOIN 或 FULL OUTER JOIN)
全连接返回左表和右表中的所有行。若某一行在另一个表中没有匹配的行,则对应的列值为 NULL。不过,MySQL 本身不直接支持 FULL JOIN,但可以通过 UNION 操作符结合左连接和右连接来实现。
语法
SELECT column1, column2, ...
FROM table1
LEFT JOIN table2
ON table1.column = table2.column
UNION
SELECT column1, column2, ...
FROM table1
RIGHT JOIN table2
ON table1.column = table2.column;
示例
SELECT customers.customer_name, orders.order_id
FROM customers
LEFT JOIN orders
ON customers.customer_id = orders.customer_id
UNION
SELECT customers.customer_name, orders.order_id
FROM customers
RIGHT JOIN orders
ON customers.customer_id = orders.customer_id;
交叉连接(CROSS JOIN)
交叉连接返回两个表的笛卡尔积,也就是左表的每一行与右表的每一行都组合一次。
语法
SELECT column1, column2, ...
FROM table1
CROSS JOIN table2;
示例
SELECT products.product_name, categories.category_name
FROM products
CROSS JOIN categories;
自连接(SELF JOIN)
自连接是指一个表与其自身进行连接,通常用于处理表中存在的层次关系。
示例
假设 employees 表包含 employee_id、employee_name 和 manager_id 列,要查询每个员工的经理姓名,可以使用自连接:
SELECT e1.employee_name, e2.employee_name AS manager_name
FROM employees e1
JOIN employees e2
ON e1.manager_id = e2.employee_id;
在这个示例中,e1 和 e2 是 employees 表的别名,分别代表员工和经理。
17. UNION 运算符
UNION 运算符用于组合两个或多个 SELECT 语句的结果集。
- 在
UNION内的每个SELECT语句都必须具有相同数量的列 - 这些列还必须具有类似的数据类型
- 每个
SELECT语句中的列也必须按相同的顺序排列
UNION 语法
SELECT *column_name(s)* FROM *table1*
UNION
SELECT *column_name(s)* FROM *table2*;
UNION ALL 语法
默认情况下,UNION 运算符仅选择不同的值。要允许重复值,请使用 UNION ALL
SELECT *column_name(s)* FROM *table1*
UNION ALL
SELECT *column_name(s)* FROM *table2*;
注意:结果集中的列名通常等于第一个 SELECT 语句中的列名。
18. GROUP BY 语句
GROUP BY 语句将具有相同值的行的分组到汇总行中,例如“查找每个国家/地区的客户数量”。
GROUP BY 语句通常与聚合函数(COUNT()、MAX()、MIN()、SUM()、AVG())一起使用,按一个或多个列对结果集进行分组。
语法
SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
ORDER BY column_name(s);
发表评论