MySQL的基础二(函数、约束、多表操作、事务)

一、函数:

MySQL是一款关系型数据库,支持使用函数来处理数据。以下是MySQL中可用的一些常用函数:

  • 字符串函数:例如CONCAT、SUBSTRING、UPPER、LOWER等
  • 数学函数:例如ABS、CEIL、FLOOR、ROUND等
  • 日期和时间函数:例如NOW、YEAR、MONTH、DAY等
  • 聚合函数:例如SUM、AVG、COUNT、MAX、MIN等
  • 控制流函数:例如IF、CASE、COALESCE等

这些函数可以在SELECT语句中使用,以帮助您查询和处理数据。例如,您可以使用CONCAT函数将两个字符串连接在一起,使用SUM函数计算数据列的总和,或使用IF函数根据条件返回不同的值。

有些函数需要传递参数,例如SUBSTRING函数需要指定要截取的字符串和要开始截取的位置。其他函数可能不需要参数,例如NOW函数返回当前日期和时间。您可以在MySQL文档中找到更多有关每个函数及其参数的详细信息。

字符串函数

CONCAT(S1,S2,…Sn)字符串拼接,将S1,S2,… Sn拼接成一个字符串

LOWER(str)将字符串str全部转为小写

UPPER(str)将字符串str全部转为大写

LPAD(str,n,pad)左填充,用字符串pad对str的左边进行填充,达到n个字符串长度

RPAD(str,n,pad)右填充,用字符串pad对str的右边进行填充,达到n个字符串长度
TRIM(str)去掉字符串头部和尾部的空格

SUBSTRING(str,start,len)返回从字符串str从start位置起的len个长度的字符串

select  concat('he','llo');
select lower('HELLo012');
//左填充可以实现以‘0’为前导,如excel一样

select  lpad('0123',5,'-');
select  rpad('0123',5,'-');
select trim(' _1 hello MySQL 1');
select  substring('helloworld',1,3);

数值函数

CEIL(×)向上取整

FLOOR(×)向下取整

MOD(Xy)返回x/y的模

RAND()返回0~1内的随机数

ROUND(x,y)求参数x的四舍五入的值,保留y位小数

日期函数

在这里插入图片描述

流程函数

在这里插入图片描述

二、约束

常见的约束有非空约束 唯一约束 主键约束 默认约束 外键约束
primary key:存在且唯一;unique:只需唯一,不一定存在

1.非空:是否可以存在null值

2.唯一:不重复

3.主键:非空的,唯一的

4.默认:

5.检查:check检查约束是否符合

6.外键:至少两张表,保证数据的一致性和严谨性
外键:其他表中的主键字段

注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。

中间不加任何符号,直接空格

id的自动增长:

主键:一个表中,只能有一个字段作为主键,并且不能为NULL,且值是唯一的(可以多列作为复合主键,当所有设置为复合主键的列都相同时视为唯一,常用于多对多的表中)。
在这里插入图片描述

不允许name为NULL值,但不要是字符串的null就行

在这里插入图片描述

唯一约束

唯一键(唯一约束):一个表中可以有多个唯一键,唯一键的值可以为NULL,但值必须保证唯一,即NULL值在表中只能出现一次,其它非NULL值也必须是唯一的。唯一键会隐式地创建唯一索引。

在这里插入图片描述

实现同样效果的

在这里插入图片描述

外键约束

外键是用来建立两张表之间的关联关系,确保数据的一致性和完整性。具有外键的表被称为子表,而拥有被引用作为主键的表被称为父表。

然而,尽管外键约束可以确保数据的完整性,但在某些情况下,它可能会对查询性能产生一定影响。这是因为在进行插入、更新或删除操作时,数据库需要检查外键约束以确保数据的一致性,这可能会增加操作的时间开销。

另外需要注意的是,外键仅仅是在逻辑上的关联关系,并不一定在数据库层面实际存在。数据库本身并不强制要求使用外键约束,因此在某些情况下,开发人员可能选择不使用外键约束。然而,在大多数情况下,使用外键约束是推荐的做法,以确保数据的完整性和一致性。

如果您希望在数据库层面建立外键关联,可以使用ALTER TABLE语句来添加外键约束。这样,在执行相关操作时,数据库会自动检查并处理外键约束,以保证数据的一致性和完整性。

语法

(1)创建的时候就添加
create table 表名(
	字段名 数据类型,
	[constraint] [外键名称] foreign key(外键字段名)references 主表(主表列名)
	);
(2)已经存在表结构
alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名);

蓝色小钥匙–外键

在这里插入图片描述

(3)删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

删除、更新

上述是关于外键约束时常见的触发器选项,它们用于定义当父表中的行被删除或更新时,子表应该如何处理相应的外键关联。

下面对各个选项进行简要说明:

  • NO ACTION/RESTRICT:当在父表中删除或更新记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。这两个选项的行为是一致的。
  • CASCADE:当在父表中删除或更新记录时,首先检查该记录是否有对应外键,如果有,则同时删除/更新外键在子表中的相关记录。
  • SET NULL:当在父表中删除记录时,首先检查该记录是否有对应外键,如果有,则将子表中该外键设置为NULL。这就要求外键允许取NULL值。
  • SET DEFAULT:当父表发生变更时,子表将外键列设置成一个默认的值。然而InnoDB存储引擎并不支持此选项。
  • 不采取行动:与NO ACTION/RESTRICT的行为是一致的,即当在父表中删除或更新记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。
  • 限制:与NO ACTION/RESTRICT的行为是一致的,即当在父表中删除或更新记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。
  • 级联:与CASCADE的行为是一致的,即当在父表中删除或更新记录时,首先检查该记录是否有对应外键,如果有,则同时删除/更新外键在子表中的相关记录。
  • 设置为空:与SET NULL的行为是一致的,即当在父表中删除记录时,首先检查该记录是否有对应外键,如果有,则将子表中该外键设置为NULL。这就要求外键允许取NULL值。
  • 设置默认值:与SET DEFAULT的行为是一致的,但InnoDB存储引擎不支持该选项。

不同的选项适用于不同的场景和需求,根据实际情况选择适合自己的选项可以更好地保证数据的完整性和一致性。

语法

以下是在MySQL中定义外键约束时的一般语法:

ALTER TABLE 子表
ADD CONSTRAINT 外键名称
FOREIGN KEY (子表外键列) 
REFERENCES 父表 (父表主键列)
[ON DELETE 动作]
[ON UPDATE 动作];
  • "子表"是包含外键的表名。
  • "外键名称"是您为外键约束指定的一个唯一名称。
  • "子表外键列"是子表中与父表关联的列名。
  • "父表"是被引用作为主键的表名。
  • "父表主键列"是父表的主键列名,它与子表的外键列相关联。

"[ON DELETE 动作]“和”[ON UPDATE 动作]"是可选项,用于指定在父表中删除或更新记录时的动作。这些动作可以是以下之一:

  • CASCADE:级联操作,在父表上执行删除或更新操作时,同时删除/更新子表中的相关记录。
  • SET NULL:将子表中的外键值设置为NULL(要求该外键允许取NULL值)。
  • SET DEFAULT:将子表中的外键值设置为默认值(InnoDB不支持此选项)。
  • NO ACTION/RESTRICT:不采取行动,阻止对父表的删除或更新操作。

示例:
假设有两个表,一个名为"orders",另一个为"customers"。我们想在"orders"表中添加外键约束,使其引用"customers"表的主键"customer_id"。如果父表中的记录被删除或更新,我们希望禁止对子表进行相应的操作。

ALTER TABLE orders
ADD CONSTRAINT fk_customer
FOREIGN KEY (customer_id)
REFERENCES customers (customer_id)
ON DELETE RESTRICT
ON UPDATE RESTRICT;

这将在"orders"表上创建一个名为"fk_customer"的外键约束,将"customer_id"列与"customers"表中的"customer_id"列关联起来,并设置了NO ACTION/RESTRICT选项来限制删除和更新操作。

图形化页面操作

在这里插入图片描述

三、多表操作

3.1 多表关系

常见的关系类型包括一对多(多对一)、多对多和一对一。

3.1.1 一对多关系

一种常见的表关系

一对多关系指的是一个表中的记录关联到另一个表中的多条记录,或者反过来,多个记录关联到另一个表中的单条记录。

  • 实现原则:

在多的一方建立外键,指向一的一方的主键在这里插入图片描述

  • 案例
    两个表:作者表(Authors)和图书表(Books)。

Authors表包含作者的信息,如作者ID(author_id)、姓名等。
Books表包含书籍的信息,如书籍ID(book_id)、书名、作者ID等。
关系说明:
一个作者可以有多本书,但一本书只能有一个作者。这就是一对多关系,或者可以说是多对一关系。

实现过程:
在Books表中,通过在author_id列上建立外键,关联到Authors表的author_id列。这样,通过作者ID,我们可以在Authors表中找到对应的作者,而在Books表中,通过author_id可以找到一本书对应的作者。

3.1.2 多对多关系

表示两个表之间存在多对多的关联,其中一个表的记录可以与另一个表的多个记录相关联,反之亦然。

  • 实现原则:

借助中间表。各取所需,中间表至少包含两个字段,将多对多的关系,拆成一对多的关系,中间表至少要有两个外键,这两个外键分别指向原来的那两张表的主键
在这里插入图片描述

  • 案例
    两个表:学生表(Students)和课程表(Courses)。

Students表包含学生的信息,如学生ID(student_id)、姓名等。
Courses表包含课程的信息,如课程ID(course_id)、课程名称等。
为了表示学生和课程之间的多对多关系,通常引入第三个表,称为选课表(Enrollments)。

Enrollments表包含学生ID和课程ID,表示哪个学生选修了哪门课程。 关系说明:
一个学生可以选修多门课程,一门课程也可以被多个学生选修。这是典型的多对多关系。

实现过程:
在Enrollments表中,学生ID和课程ID都作为外键,分别关联到Students表和Courses表的主键。这样,可以通过Enrollments表来查找学生选修的课程,以及课程被哪些学生选修。
在这里插入图片描述

3.1.3 一对一关系:

表示两个表之间的记录是一对一的关联,每个记录在另一个表中都有唯一对应的记录

一对一关系的实现通常涉及将相同的主键值分配给两个不同的表,
	使得这两个表之间存在一对一的关联。
一对一关系的核心是使用相同的主键值将两个表连接在一起,
	使得每个记录在两个表中都有唯一的对应。
具体而言,两个表中的主键值相互对应,
	确保每个记录在其中一个表中都有唯一的对应记录在另一个表中。
  • 实现原则:

在任一表中添加唯一外键,指向另一方主键,确保一对一关系。将常用字段和不常用字段拆分成两张表,使用同样的主键对应
在这里插入图片描述

  • 举例案例:
    考虑两个表:员工表(Employees)和员工详情表(EmployeeDetails)。

Employees表包含员工的基本信息,如员工ID(employee_id)、姓名等。
EmployeeDetails表包含员工的详细信息,如员工ID、地址、联系方式等。 关系说明:
每个员工在Employees表中有唯一的记录,对应到EmployeeDetails表中也有唯一的记录。这是一对一关系。

实现过程:
在EmployeeDetails表中,员工ID作为外键关联到Employees表的员工ID主键。这样,每个员工在EmployeeDetails表中都有对应的唯一记录,建立了一对一的关系。

3.2 多表查询

指在查询数据库时涉及多个表的操作。

下面演示的部分数据库信息的结构来源是GPT的

3.2.1 了解

表表间的关系分为:交叉连接(Cross Join)、内连接(Inner Join)、外连接(outer join)、子查询、自连接。
我们需要

A)内连接:A,B两表交集部分
JOIN INNER JOIN

B)外连接:查询指定方向的数据以及交集的部分
左外连接:
LEFT JOIN LEFT OUTER JOIN
右外连接:

RIGHT JOIN RIGHT OUTER JOIN
全外连接:

FULL JOIN FULL OUTER JOIN UNION(这不是外连接,但是在某些情况下可以达到合并两个表的效果)

C)交叉连接:

CROSS JOIN

  • (1)交叉连接(Cross Join)
  • 又被称为笛卡尔积,交叉连接返回两个表的笛卡尔积,即其中一个表的每一行都与另一个表的每一行组合。
# 明确使用了交叉连接(CROSS JOIN)
select *from emp cross join dept;

# 隐式使用交叉连接
select * from emp,dept
  • (2)内连接:
# 隐式内连接
select * from A,B where 条件;

#  显示内连接
select * from A [inner] join B on 条件;
  • (3)外连接查询

  • 左外连接
    SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ... ;

  • 右外连接
    SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ... ;

  • 满外连接:
    select * from A full outer join B on 条件;

  • (4)子查询
    子查询是指在一个查询内部嵌套的查询,可以作为其他查询的一部分。

  • (5)表自关联
    指在同一表内进行连接操作,通常通过在表中的不同列之间建立关联,使得表内的不同行之间可以进行关联查询。

3.2.2 内连接(表之间交集部分)

(1)格式

内连接的查询基于表关系的共同值,这些共同值是连接条件的基础。

# 隐式内连接
select * from A,B where 条件; 
# 显式内连接 -- 真心推荐
select * from A [inner] join B on 连接条件;
(2)案例
  • (1)数据准备
-- 创建 Customers 表
CREATE TABLE Customers (
    customer_id INT PRIMARY KEY,
    customer_name VARCHAR(255),
    country VARCHAR(255)
);

-- 插入示例数据到 Customers 表
INSERT INTO Customers (customer_id, customer_name, country) VALUES
(1, 'Alice', 'USA'),
(2, 'Bob', 'Canada'),
(3, 'Charlie', 'UK'),
(4, 'David', 'Australia'),
(5, 'Emma', 'Germany');

-- 创建 Orders 表
CREATE TABLE Orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES Customers(customer_id)
);

-- 插入示例数据到 Orders 表
INSERT INTO Orders (order_id, customer_id, order_date) VALUES
(101, 1, '2023-01-15'),
(102, 2, '2023-01-16'),
(103, 1, '2023-01-17'),
(104, 4, '2023-01-18'),
(105, 3, '2023-01-19');

在这里插入图片描述

  • (2)内连接语句
SELECT c.customer_id, c.customer_name, c.country, o.order_id, o.order_date
FROM Customers c
INNER JOIN Orders o ON c.customer_id = o.customer_id;

在这里插入图片描述
注意我们一旦起了别名,就得一直运用别名,不能用原来的名称代替原本你的字段了。
这和我们在学Python中引入他库的换名是一样的道理。

3.2.3 外连接

(1)格式
  • 【1】左外连接:left outer join
  select * from A left outer join B on 条件;

左外连接以左表(employees)为基准,返回左表中的所有行,以及右表(departments)中与左表匹配的行。如果右表中没有匹配的行,结果集中将包含 NULL 值。

  • 【2】 右外连接:right outer join
select * from A right outer join B on 条件;

右外连接以右表(departments)为基准,返回右表中的所有行,以及左表(employees)中与右表匹配的行。如果左表中没有匹配的行,结果集中将包含 NULL 值。

(2)案例
  • (1)数据准备
CREATE TABLE departments (
    department_id INT PRIMARY KEY,
    department_name VARCHAR(255)
);

INSERT INTO departments (department_id, department_name) VALUES
(1, 'HR'),
(2, 'IT'),
(3, 'Finance');
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    employee_name VARCHAR(255),
    department_id INT,
    FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

INSERT INTO employees (employee_id, employee_name, department_id) VALUES
(1, 'John Doe', 1),
(2, 'Jane Smith', 2),
(3, 'Bob Johnson', 1),
(4, 'Alice Brown', NULL),
(5, 'Charlie Green', 2);

在这里插入图片描述
在这里插入图片描述

  • (2)左外连接:left outer join
SELECT e.employee_id, e.employee_name, d.department_name,d.department_id
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id;

在这里插入图片描述

  • (3)右外连接:right outer join
SELECT e.employee_id, e.employee_name, d.department_name,d.department_id
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.department_id;

在这里插入图片描述

(3)看看GPT怎么说

左外连接和右外连接是外连接的两种类型,它们分别以左表和右表为基准,保留左表或右表的所有行,同时匹配右表或左表中的相应行。让我们通过案例说明这两种连接的含义:

左外连接(Left Outer Join):

左外连接以左表(employees)为基准,返回左表中的所有行,以及右表(departments)中与左表匹配的行。如果右表中没有匹配的行,结果集中将包含 NULL 值。

SELECT employees.employee_id, employees.employee_name, departments.department_name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.department_id;
结果解释:
  • 对于员工表 employees

    +-------------+--------------+---------------+
    | employee_id | employee_name| department_id |
    +-------------+--------------+---------------+
    |      1      |   John Doe   |       1       |
    |      2      |  Jane Smith  |       2       |
    |      3      | Bob Johnson  |       1       |
    |      4      | Alice Brown  |      NULL     |
    |      5      |Charlie Green |       2       |
    +-------------+--------------+---------------+
    
  • 对于部门表 departments

    +----------------+-------------------+
    | department_id  | department_name  |
    +----------------+-------------------+
    |        1       |        HR         |
    |        2       |        IT         |
    |        3       |      Finance      |
    +----------------+-------------------+
    
  • 左外连接的结果:

    +-------------+--------------+-------------------+
    | employee_id | employee_name| department_name  |
    +-------------+--------------+-------------------+
    |      1      |   John Doe   |        HR         |
    |      2      |  Jane Smith  |        IT         |
    |      3      | Bob Johnson  |        HR         |
    |      4      | Alice Brown  |       NULL        |
    |      5      |Charlie Green |        IT         |
    +-------------+--------------+-------------------+
    

在结果中,左表 employees 的所有行都被包含,而右表 departments 中匹配的部门名称也被添加到结果中。注意到员工 Alice Brown 没有分配到部门,因此在结果中,对应的部门名称显示为 NULL。

右外连接(Right Outer Join):

右外连接以右表(departments)为基准,返回右表中的所有行,以及左表(employees)中与右表匹配的行。如果左表中没有匹配的行,结果集中将包含 NULL 值。

SELECT employees.employee_id, employees.employee_name, departments.department_name
FROM employees
RIGHT JOIN departments ON employees.department_id = departments.department_id;
结果解释:
  • 左表 employees 同上。

  • 右表 departments 同上。

  • 右外连接的结果:

    +-------------+--------------+-------------------+
    | employee_id | employee_name| department_name  |
    +-------------+--------------+-------------------+
    |      1      |   John Doe   |        HR         |
    |      2      |  Jane Smith  |        IT         |
    |      3      | Bob Johnson  |        HR         |
    |      4      | Alice Brown  |       NULL        |
    |      5      |Charlie Green |        IT         |
    |    NULL     |     NULL     |      Finance      |
    +-------------+--------------+-------------------+
    

右外连接的结果中包含了右表 departments 的所有行,而左表 employees 中匹配的员工信息也被添加到结果中。注意到部门 Finance 没有员工,因此在结果中,对应的员工信息显示为 NULL。

这两个例子展示了左外连接和右外连接的用法和含义。左外连接保留左表的所有行,并匹配右表的相应行;右外连接保留右表的所有行,并匹配左表的相应行。在实际应用中,根据查询需求选择适当的连接方式。如果有其他问题或需要更多解释,请随时提问。

3.2.4 自连接查询

(1)格式

自连接是指在同一表内进行连接操作,通常用于比较表内不同行之间的数据。

SELECT t1.column, t2.column FROM table t1, table t2 WHERE t1.column = t2.column;

(2)案例
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    employee_name VARCHAR(50),
    manager_id INT
);

INSERT INTO employees VALUES
(1, 'John', 3),
(2, 'Alice', 3),
(3, 'Bob', NULL),
(4, 'Charlie', 2),
(5, 'David', 2);

在这里插入图片描述

[1]无外连接:
在这里插入图片描述

[2]用左外连接,除了要求字段值匹配以外,哪怕manager_id为空也能查出
在这里插入图片描述

3.2.5 联合查询union,union all

(1)说明

UNIONUNION ALL 是用于联合查询的 SQL 操作符,它们用于将两个或多个 SELECT 语句的结果合并成一个结果集。以下是它们的主要区别:

UNION:
  • 去重: UNION 操作符用于合并两个或多个 SELECT 语句的结果,并自动去除重复的行。

  • 示例:

    SELECT column1, column2 FROM table1
    UNION
    SELECT column1, column2 FROM table2;
    
  • 注意事项:

    • 列数和数据类型必须匹配。
    • 结果集中不包含重复的行。
UNION ALL:
  • 保留重复行: UNION ALL 也用于合并两个或多个 SELECT 语句的结果,但不去除重复的行,保留所有行。

  • 示例:

    SELECT column1, column2 FROM table1
    UNION ALL
    SELECT column1, column2 FROM table2;
    
  • 注意事项:

    • 列数和数据类型必须匹配。
    • 结果集中可能包含重复的行。

在选择使用 UNION 还是 UNION ALL 时,需要考虑是否需要去重。如果你希望结果集中不包含重复的行,可以使用 UNION。如果允许重复行,并且希望保留所有行,可以使用 UNION ALL,它通常比 UNION 更快,因为不需要执行去重的操作。

总体而言,UNIONUNION ALL 提供了在 SQL 查询中合并结果集的强大工具,可以根据具体需求选择适当的操作符。希望这能帮助你理解它们的区别和使用场景。如果有其他问题,请随时提问。

(2)案例

在这里插入图片描述

【1】union
在这里插入图片描述

【2】要去重就是把all关键字去掉
在这里插入图片描述

(3)总结

列数一致: 在使用 UNION 或 UNION ALL 进行联合查询时,每个 SELECT 语句中选择的列数量必须相同。例如,如果在第一个 SELECT 中选择了3列,那么在后续的 SELECT 中也必须选择3列,且每一列的位置和类型都要匹配。

字段类型一致: 对应位置的列在不同表中的数据类型必须一致。如果第一个表的某一列是整数,那么其他表中对应的列也必须是整数。

关于您提到的联合查询会对合并后的数据去重,这是对于 UNION 操作而言的,它确实会对结果进行去重,确保最终结果中的行是唯一的。而 UNION ALL 则不进行去重,直接将所有数据合并。

3.2.6 子查询

(1)格式
子查询是在另一个查询内部嵌套的查询,可以作为其他查询的一部分。
SELECT * FROM table1 WHERE column IN (SELECT column FROM table2 WHERE condition);

(2)说明

在 SQL 中,子查询(Subquery)是指嵌套在主查询中的查询。子查询可以根据其结果的形状分为四类:标量子查询(Scalar Subquery)、列子查询(Column Subquery)、行子查询(Row Subquery)、表子查询(Table Subquery)。下面将对每种类型进行解释并提供相应的示例:

1. 标量子查询(Scalar Subquery):
  • 常用的操作符 = <> > >= < <=

  • 定义: 子查询结果为单个值。

  • 示例:

    SELECT column_name, (SELECT MAX(salary) FROM employees) AS max_salary
    FROM employees;
    

在上述示例中,(SELECT MAX(salary) FROM employees) 是一个标量子查询,返回了 employees 表中的最大薪资值。

2. 列子查询(Column Subquery):
  • 常用的操作符
  1. IN 操作符:
  • 描述: 在指定的集合范围内,选择满足条件的值。

  • 示例: sql SELECT column_name FROM table_name WHERE column_name IN (value1, value2, ...);

  1. NOT IN 操作符:
  • 描述: 不在指定的集合范围内选择满足条件的值。

  • 示例: sql SELECT column_name FROM table_name WHERE column_name NOT IN (value1, value2, ...);

  1. ANY/SOME 操作符:
  • 描述: 子查询返回列表中,有任意一个满足条件即可。

  • 示例: sql SELECT column_name FROM table_name WHERE column_name > ANY (SELECT another_column FROM another_table);

  1. ALL 操作符:
  • 描述: 子查询返回列表的所有值都必须满足条件。

  • 示例: sql SELECT column_name FROM table_name WHERE column_name > ALL (SELECT another_column FROM another_table);
    EXISTS 是 SQL 中的一个关键字,用于检查子查询是否返回了任何行。以下是对 EXISTS 的描述:

  1. EXISTS 关键字:
  • 描述: EXISTS 用于检查子查询是否返回任何行。如果子查询返回了至少一行结果,那么 EXISTS 返回 TRUE,否则返回 FALSE

  • 示例: sql SELECT column_name FROM table_name WHERE EXISTS (SELECT 1 FROM another_table WHERE condition);

在上述示例中,如果子查询 (SELECT 1 FROM another_table WHERE condition)
返回了至少一行记录,那么外部查询就会选择满足条件的行。

EXISTS 常用于子查询的条件判断,常见的用法包括在 WHERE 子句中使用它来检查某个条件是否成立。

  • 定义: 子查询结果为一列。

  • 示例:

    SELECT column_name
    FROM table1
    WHERE column_name IN (SELECT column_name FROM table2);
    

在这个示例中,(SELECT column_name FROM table2) 是一个列子查询,返回了 table2 表中的某一列。

3. 行子查询(Row Subquery):
  • 常用的操作符:=、<>、IN、NOT IN

  • 定义: 子查询结果为一行。

  • 示例:

    SELECT column_name
    FROM table1
    WHERE (column1, column2) = (SELECT value1, value2 FROM table2);
    

在这个示例中,(SELECT value1, value2 FROM table2) 是一个行子查询,返回了 table2 表中的一行数据。

4. 表子查询(Table Subquery):
  • 常用的操作符:IN

  • 定义: 子查询结果为多行多列。

  • 示例:

    SELECT column_name1, column_name2
    FROM table1
    WHERE (column1, column2) IN (SELECT value1, value2 FROM table2);
    

在这个示例中,(SELECT value1, value2 FROM table2) 是一个表子查询,返回了 table2 表中的多行多列数据。

这些子查询类型可以根据查询结果的形状和期望的对比方式进行选择。子查询在 SQL 中用于构建复杂的查询逻辑,并且可以嵌套多层。希望这些示例有助于理解不同类型的子查询及其应用场景。如果有其他问题,请随时提问。

(3)案例
CREATE TABLE Authors (
    author_id INT PRIMARY KEY,
    author_name VARCHAR(50)
);

INSERT INTO Authors (author_id, author_name) VALUES
(1, 'Author A'),
(2, 'Author B'),
(3, 'Author C');


CREATE TABLE Books (
    book_id INT PRIMARY KEY,
    book_title VARCHAR(100),
    author_id INT,
    FOREIGN KEY (author_id) REFERENCES Authors(author_id)
);

INSERT INTO Books (book_id, book_title, author_id) VALUES
(101, 'Book 1 Title', 1),
(102, 'Book 2 Title', 1),
(103, 'Book 3 Title', 2),
(104, 'Book 4 Title', 2),
(105, 'Book 5 Title', 3);

在这里插入**加粗样式**图片描述

(4)案例说明

子查询是在一个 SQL 查询中嵌套另一个查询的查询方式。下面是一个使用子查询的示例,以图书的数据库为例:

假设有两个表:Authors 表和 Books 表。

Authors 表:
author_idauthor_name
1Author A
2Author B
3Author C
Books 表:
book_idbook_titleauthor_id
101Book 1 Title1
102Book 2 Title1
103Book 3 Title2
104Book 4 Title2
105Book 5 Title3
示例 1:使用子查询获取作者名字和他们的书籍数量
SELECT 
    author_name,
    (SELECT COUNT(*) FROM Books WHERE Authors.author_id = Books.author_id) AS book_count
FROM Authors;

在这个例子中,子查询 (SELECT COUNT(*) FROM Books WHERE Authors.author_id = Books.author_id) 被嵌套在主查询中。它计算了每个作者的书籍数量,并且主查询选择了作者的名字和子查询计算的书籍数量。

在这里插入图片描述

示例 2:使用子查询筛选出作者写的书籍数量大于1的作者
SELECT 
    author_name
FROM Authors
WHERE (SELECT COUNT(*) FROM Books WHERE Authors.author_id = Books.author_id) > 1;

这个例子中,子查询被用作 WHERE 子句的条件,筛选出写了书籍数量大于2的作者。

四、事务

MySQL的事务是一系列数据库操作的逻辑单元,用于确保数据库操作的一致性和可靠性。事务可以将一组相关的操作绑定在一起,并要么全部成功执行,要么全部回滚,以保持数据库在任何时间点的一致性。

4.1 ACID属性

在MySQL中,事务具有ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。这些属性确保了事务的可靠性和正确性。
在这里插入图片描述

4.2 操作

回滚事务:使用ROLLBACK语句来回滚事务,即撤销所有对数据库的修改,恢复到事务开始之前的状态

查看默认提交方式:SELECT @@autocommit; 1代表自动提交,0代表手动提交
修改默认提交方式:SET @@autocommit = 0;
1代表自动提交,0代表手动提交

在这里插入图片描述

4.3 可能会出现的问题

简单来说,不可重复度是数据值前后不一致,幻读是数据行前后不一致
在这里插入图片描述

4.4 隔离级别

隔离级别越高,可能会导致并发性能下降。因为较高的隔离级别可能需要使用锁定机制来确保数据的一致性,而锁定数据会限制其他事务的访问,从而降低了并发能力。
在这里插入图片描述

关系
在这里插入图片描述
在这里插入图片描述

4.5 设置

在这里插入图片描述

在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你会魔法吗✧(≖ ◡ ≖✿)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值