当前位置:   article > 正文

如何一招学会SQL语句查询操作?_sql怎么查询

sql怎么查询

单表查询

基础查询 

select

        字段列表

from

        表名列表

where

        条件列表

group by

        分组字段

having

分组后的条件

order by

排序字段

limit

分页限定

数据库表stu

基础查询

1. 查询多个字段

select 字段列表 from 表名;

select * from 表名; --- 查询所有数据

2. 去除重复记录

select distinct 字段列表 from 表名;

3. 起别名

as

条件查询

1. 条件查询语法:

select 字段列表 from 表名 where 条件列表;

排序查询

select 字段列表 from 表名 order by 排序字段名 [排序方式1], 排序字段名2 [排序方式2], ....

排序方式:

        ASC: 升序(默认值) 

        DESC:降序

聚合函数

语法:select 聚合函数名(列名) FROM 表;
    分类:
            * count(列名) 统计数量
                    取值:
                            * 1.主键
                            * 2. *
            * max(列名) 最大值
            * min(列名) 最小值
            * sum(列名) 求和
            * avg(列名) 平均值
    注意:null值不参与所有聚合函数运算

分组查询

分组函数:
          语法:select 字段列表 FROM 表名 [WHERE 分组前条件限定] GROUP BY 分组字段名 [HAVING 分组后条件过滤]...;

    注意:分组之后,查询字段为聚合函数和分组字段

    执行顺序:where > 聚合函数 > having

分页查询

语法:select 字段列表 FROM 表名 LIMIT 起始索引 , 查询条目数;
            起始索引:从0开始

    计算公式:起始索引 = (当前页码-1)* 每页显示的条数

实例分析:

-- 创建stu表
CREATE TABLE stu (
    id INT,   -- 编号
    name VARCHAR(20),  -- 姓名
    age int, -- 年龄
    sex varchar(5), -- 性别
    address varchar(100),  -- 地址
    math double(5,2),   -- 数学成绩
    english double(5,2),  -- 英语成绩
    hire_date date    -- 入学日期
);
-- 添加数据
INSERT INTO stu(id,name,age,sex,address,math,english,hire_date)
VALUES 
(1, '马运', 55, '男', '杭州', 66, 78, '1995-09-01'),
(2, '马花移', 45, '女', '深圳', 98, 87, '1998-09-1'),
(3, '马斯克', 55, '男', '香港', 56, 77, '1999-09-02'),
(4, '柳白', 20, '女', '湖南', 76, 65, '1997-09-05'),
(5, '柳青', 20, '男', '湖南', 86, null, '1998-09-01'),
(6, '刘德花', 57, '男', '香港', 99, 99, '1999-09-01'),
(7, '张学有', 22, '女', '香港', 99, 99, '1999-09-01'),
(8, '德玛西亚', 18, '男', '南京', 56, 65, '1994-09-02');

-- 基础查询 =================
-- 查询name, age 两列
SELECT name, age from stu;

-- 查询所有列的数据
SELECT id, name, age, sex, address, math, english, hire_date
FROM stu;

SELECT * FROM stu;   -- 编码习惯不建议用 * 

-- 查询地址
SELECT address FROM stu;

-- 去除重复
SELECT DISTINCT address FROM stu;

-- 查询姓名,数学成绩,英语成绩
SELECT name, math, english FROM stu;

-- 起别名
SELECT name, math 数学成绩, english as 英语成绩  FROM stu;


-- 条件查询 ================
-- 1. 查询年龄大于20岁的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age > 20;

-- 2.查询年龄等于20岁的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age >= 20;

-- 3.查询年龄大于等于20岁 并且 小于等于30岁的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age >= 20 AND age <= 30;

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age BETWEEN 20 and 30;

-- 4.查询入学日期在'1998-09-01'到'1999-09-01'之间的学员信息

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE hire_date BETWEEN '1998-09-01' and '1999-09-01';

-- 5.查询年龄等于18岁的学员信息

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age = 18;

-- 6.查询年龄不等于18岁的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age != 18;

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age <> 18;


-- 7.查询年龄等于18岁 或 年龄等于20 或 年龄等于22的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age = 18 or age = 20 or age = 22;

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE age in (18,20,22);

-- 8.查询英语成绩为null的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE english = null;

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE english IS null;

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE english IS NOT null;

-- 模糊查询 LIKE =======================
/*
    通配符:
            1) _ :代表单个任意字符
            2) % :代表任意多个字符
*/
-- 1. 查询姓 '马' 的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE name LIKE '马%';

-- 2. 查询第二个字是'花'的学员信息
SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE name LIKE '_花%';

-- 3. 查询名字中包含'德'的学员信息

SELECT id, name, age, sex, address, math, english, hire_date FROM stu WHERE name LIKE '%德%';

-- 排序查询 ======================
/*
    排序查询:
            * 语法:select 字段列表 from 表名 order by 排序字段名 [排序方式1], 排序字段名2 [排序方式2], ....
            * 排序方式:
                        * ASC: 升序(默认值) 
                        * DESC:降序
*/

-- 1.查询学生信息,按照年龄升序排列
SELECT id, name, age, sex, address, math, english, hire_date FROM stu ORDER BY age ASC;

-- 2.查询学生信息,按照数学成绩降序排列
SELECT id, name, age, sex, address, math, english, hire_date FROM stu ORDER BY math DESC;

-- 3.查询学生信息,按照数学成绩降序排列,如果数学成绩一样,按照英语成绩升序排列
SELECT id, name, age, sex, address, math, english, hire_date FROM stu ORDER BY math DESC , english ASC;

-- 聚合函数 =====================
/*
    语法:select 聚合函数名(列名) FROM 表;
    分类:
            * count(列名) 统计数量
                    取值:
                            * 1.主键
                            * 2. *
            * max(列名) 最大值
            * min(列名) 最小值
            * sum(列名) 求和
            * avg(列名) 平均值
    注意:null值不参与所有聚合函数运算
*/
-- 1. 统计班级一共有多少学生
SELECT COUNT(id) FROM stu;   -- count统计的列名不能是null
SELECT COUNT(*) FROM stu;

-- 2.查询数学成绩的最高分
SELECT MAX(math) FROM stu; 

-- 3.查询数学成绩的最低分
SELECT MIN(math) FROM stu; 

-- 4.查询数学成绩总分
SELECT sum(math) FROM stu; 

-- 5.查询数学成绩平均分
SELECT avg(math) FROM stu; 

-- 6.查询英语成绩的最低分
SELECT min(english) FROM stu; 

-- 分组查询 ==========================
/*
    分组函数:
          语法:select 字段列表 FROM 表名 [WHERE 分组前条件限定] GROUP BY 分组字段名 [HAVING 分组后条件过滤]...;

    注意:分组之后,查询字段为聚合函数和分组字段

    执行顺序:where > 聚合函数 > having
*/
-- 1.查询男同学和女同学各自的数学平均分
SELECT sex, avg(math) FROM stu GROUP BY sex;

-- 2.查询男同学和女同学各自的数学平均分,以及各自人数
SELECT sex, avg(math), COUNT(id) FROM stu GROUP BY sex;

-- 3.查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组
SELECT sex, avg(math), COUNT(id) FROM stu WHERE math >= 70 GROUP BY sex; 

-- 4.查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组,分组之后人数大于2个
SELECT sex, avg(math), COUNT(id) FROM stu WHERE math >= 70 GROUP BY sex HAVING COUNT(id) > 2; 

-- 分页查询 =============================
/*
    语法:select 字段列表 FROM 表名 LIMIT 起始索引 , 查询条目数;
            起始索引:从0开始

    计算公式:起始索引 = (当前页码 - 1)* 每页显示的条数
*/
-- 1.从0开始查询,查询3条数据
SELECT id, name, age, sex, address, math, english, hire_date FROM stu LIMIT 0 , 3;

-- 2.每页显示3条数据,查询第1页数据
SELECT id, name, age, sex, address, math, english, hire_date FROM stu LIMIT 0 , 3;

-- 3.每页显示3数据,查询第2页数据
SELECT id, name, age, sex, address, math, english, hire_date FROM stu LIMIT 3 , 3;

-- 4.每页显示3条数据,查询第3页数据
SELECT id, name, age, sex, address, math, english, hire_date FROM stu LIMIT 6 , 3;

数据库的约束

-- 约束 案例分析=========================
-- 创建员工表
DROP TABLE IF EXISTS emp;

-- 员工表
CREATE TABLE emp (
    id INT PRIMARY KEY auto_increment,   -- 员工id , 主键且自增长
    ename VARCHAR(50) NOT NULL UNIQUE,    -- 员工姓名,非空且唯一
    joindate DATE NOT NULL,   -- 入职日期,非空
    salary DOUBLE(7,2) NOT NULL, -- 工资,非空
    bonus DOUBLE(7,2) DEFAULT 0    -- 奖金,如果没有奖金默认为0
);

-- 添加数据
INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (1, '张三', '1999-11-11', 8000, 5000);

SELECT * FROM emp;

-- 演示主键约束,非空且唯一
INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (null, '张三', '1999-11-11', 8000, 5000);

INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (1, '张三', '1999-11-11', 8000, 5000);

INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (2, '小红', '1999-11-11', 8000, 5000);

-- 演示非空约束
INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (2, 'null', '1999-11-11', 8000, 5000);

-- 演示唯一约束
INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (3, '小红', '1999-11-11', 8000, 5000);

-- 演示默认约束
INSERT INTO emp(id, ename, joindate, salary)
VALUES (3, '小华', '1999-11-11', 8000);

INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (4, '小刚', '1999-11-11', 8000, null);

-- 演示自增长
INSERT INTO emp(ename, joindate, salary, bonus)
VALUES ('小李', '1999-11-11', 8000, null);

INSERT INTO emp(id, ename, joindate, salary, bonus)
VALUES (null, '小李', '1999-11-11', 8000, null);

-- 外键约束 ===================
DROP TABLE IF EXISTS dept;
-- 部门表
CREATE TABLE dept (
    id INT PRIMARY KEY auto_increment,
    dept_name VARCHAR(20),
    addr VARCHAR(20)
);

DROP table IF EXISTS emp;
-- 员工表
CREATE TABLE emp (
    id INT PRIMARY KEY auto_increment,
    name VARCHAR(20),
  age INT,
    dept_id INT,

-- 添加外键 dept_id, 关联dept表的主键
    CONSTRAINT fk_emp_dept FOREIGN KEY (dept_id) REFERENCES dept(id)
);

SELECT * FROM emp;

SELECT * FROM dept;

-- 添加2个部门
INSERT INTO dept(id, dept_name, addr)
VALUES (1, '研发部', '深圳');
INSERT INTO dept(dept_name, addr)
VALUES ('行政部', '深圳');

-- 添加员工信息
INSERT INTO emp(name, age, dept_id)
VALUES ('小红', 20, 1);
INSERT INTO emp(name, age, dept_id)
VALUES ('小军', 20, 1);
INSERT INTO emp(name, age, dept_id)
VALUES ('小刚', 20, 1);

-- 删除外键
ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept;

-- 建完表后,添加外键
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept FOREIGN KEY (dept_id) REFERENCES dept(id);
 

 

数据库设计

1. 软件的研发步骤:

 2. 数据库设计概念:

数据库设计就是根据业务系统的具体需求,结合我们所运用的DBMS,为这个业务系统构造出最优的数据存储模型。

建立数据库中的表结构以及表与表之间的关联关系的过程。

有哪些表?表里有哪些字段?表和表之间的有什么关系?

3. 数据库设计的步骤:

需求分析(数据是什么?数据具有哪些属性?数据与属性的特点是什么?)

逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)

物理设计(根据数据库自身的特点把逻辑设计转为物理设计)

维护设计(对新的需求进行建表;表优化)

Q1:数据库设计设计什么?

Q2:数据库表关系是什么?

表关系的1:N

实现方式:在的一端建立外键,指向1的一端。

表关系的M:N

实现方式:建立第三张表,中间表至少包含两个外键,分别关联两方主键

表关系的1:1

1:1关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能。

实现方式:在任意一方加入外键,关联另一方主键,并且设置外键为唯一(unique)

案例分析:

分析设计表:

分析表字段:

专辑表

曲目表

 

 短评表

用户表

 

 

多表查询

DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;

# 创建部门表
CREATE TABLE dept (
    did INT PRIMARY KEY auto_increment,
    dname VARCHAR(20)
);

# 创建员工表
CREATE TABLE emp (
    id INT PRIMARY KEY auto_increment,
    name VARCHAR(10),
    gender CHAR(1),
    salary DOUBLE(7,2),
    join_date DATE,
    dept_id INT,
    FOREIGN KEY (dept_id) REFERENCES dept(did)
);

-- 添加部门数据
INSERT INTO dept(dname) VALUES
('研发部'),('市场部'),('财务部'),('销售部');


-- 添加员工数据
INSERT INTO emp(name,gender,salary,join_date,dept_id) VALUES
('孙悟空','男',7200,'2013-02-24',1),
('猪八戒','男',3600,'2010-12-02',2),
('唐僧','男',9000,'2008-08-08',2),
('白骨精','女',5000,'2015-10-07',3),
('蜘蛛精','女',4500,'2011-03-14',1),
('小白龙','男',2500,'2011-02-14',null);

-- 笛卡尔积:有A , B两个集合,取A,B所有的组合情况

多表查询:从多张表中查询数据

  •         连接查询:
  •                 内连接:相当于查找A,B的交集数据。
  •                 外连接:                                          
    •               左外连接:相当于查询A表数据和交集部分的数据
      •        右外连接:相当于查询B表所有数据和交集部分数据
    • 子查询

内连接语法:

隐式内连接

select 字段列表 from 表1,表2 where 条件;

显式内连接

select 字段列表 from 表1 [inner] join 表2 on 条件;

 内连接相当于查询A,B交集部分。

外连接语法:

左外连接:

select 字段列表 from 表1 left [outer] join  表2 on 条件;

右外连接:

select 字段列表 from 表1 right[outer] join  表2 on 条件;

左外连接:相当于查询A表所有数据和交集部分。

右外连接:相当于查询B表所有数据和交集部分。

子查询:

1. 子查询概念:查询中嵌套查询,称为嵌套子查询。

2. 子查询根据查询结果不同,作用不同:

  • 单行单列:作为条件值。使用= != > <作为条件判断。

select 字段列表 from 表 where 字段名 = (子查询);

  • 多行单列:作为条件值,使用in等关键字进行条件判断。

select 字段列表 from 表 where 字段名 in (子查询);

  • 多行多列:作为虚拟表

select 字段列表 from (子查询) where 条件;

实例学习记录

-- 多表查询
SELECT * FROM emp , dept;

-- 笛卡尔积:有A , B两个集合,取A,B所有的组合情况

-- 消除无效数据
-- 隐式内连接
SELECT * FROM emp , dept WHERE emp.dept_id = dept.did;

-- 查询emp表的name, gender, dept表的name
SELECT emp.`name`,emp.gender,dept.dname FROM emp t1, dept t2 WHERE t1.dept_id = t2.did;

-- 显式内连接
SELECT emp.`name`,emp.gender,dept.dname FROM emp INNER join dept on emp.dept_id = dept.did;

SELECT emp.`name`,emp.gender,dept.dname FROM emp join dept on emp.dept_id = dept.did;

-- 左外连接
-- 查询emp表所有数据和对应的部门信息
SELECT * FROM emp LEFT JOIN dept on emp.dept_id = dept.did;

-- 右外连接
-- 查询dept表所有数据和对应的员工信息
SELECT * FROM emp RIGHT JOIN dept on emp.dept_id = dept.did;

-- 子查询
-- 查询工资高于猪八戒的员工信息
SELECT * FROM emp;

-- 1. 查询猪八戒的工资
SELECT salary FROM emp WHERE `name` = '猪八戒';

-- 2。 查询工资高于猪八戒的员工信息
SELECT * FROM emp WHERE salary > 3600;

SELECT * FROM emp WHERE salary > (SELECT salary FROM emp WHERE `name` = '猪八戒');

-- 查询'财务部'和'市场部'的员工信息
SELECT did FROM dept WHERE dname='财务部' or dname='市场部';

SELECT * FROM emp WHERE dept_id in (SELECT did FROM dept WHERE dname='财务部' or dname='市场部');

-- 查询入职日期是'2011-11-11'之后的员工信息和部门信息

    -- 1. 查询入职日期是'2011-11-11'之后的员工信息
    SELECT * FROM emp WHERE join_date > '2011-11-11';

    -- 2. 查询员工信息和部门信息
    SELECT * FROM emp , dept WHERE emp.dept_id = dept.did;

SELECT * FROM (SELECT * FROM emp WHERE join_date > '2011-11-11') t1 , dept WHERE t1.dept_id = dept.did;
 

多表查询实际案例自我练习

-- 案例练习 ========================

-- 1. 查询所有员工信息,查询员工编号,员工姓名,工资,职务名称,职务描述

-- 2. 查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置

-- 3. 查询员工姓名,工资,工资等级

-- 4. 查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级

-- 5. 查询部门编号,部门名称,部门位置,部门人数


DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;
DROP TABLE IF EXISTS job;
DROP TABLE IF EXISTS salarygrade;

-- 部门表
CREATE TABLE dept (
    id INT PRIMARY KEY, -- 部门id 
    dname VARCHAR(50),  -- 部门名称
    loc VARCHAR(50)   -- 部门位置
);

-- 职务表
CREATE TABLE job(
    id INT PRIMARY KEY,  -- 职务id 
    jname VARCHAR(20),  -- 职务名称
    description VARCHAR(50)  -- 职务描述
);

-- 员工表
CREATE TABLE emp (
    id INT PRIMARY KEY, 
    ename VARCHAR(50),
    job_id INT,
    mgr int,  -- 管理者id
    joindate DATE, 
    salary DOUBLE(7,2),
    bonus DOUBLE(7,2),
    dept_id INT  
);

-- 工资等级
CREATE TABLE salarygrade (
    grade INT PRIMARY KEY,  -- 等级编号
    lowsalary INT,  -- 最低工资
    highsalary INT   -- 最高工资
);

分析思路:

-- 案例学习 ========================

-- 1. 查询所有员工信息,查询员工编号,员工姓名,工资,职务名称,职务描述
/*
    分析:
            1. 员工编号,员工姓名,工资在emp表中
            2. 职务名称,职务描述 在job中
            3. job表和emp表 是1:N联系 条件:emp.job_id = joo.id
*/
-- 隐式内连接
SELECT
    emp.id,
    emp.ename,
    emp.salary,
    job.jname,
    job.description
FROM
    emp,
    job
WHERE
    emp.job_id = job.id;


-- 验证:
    SELECT * from emp;
    SELECT * FROM job;
-- 显式内连接
SELECT
    emp.id,
    emp.ename,
    emp.salary,
    job.jname,
    job.description
FROM
    emp
INNER JOIN job ON emp.job_id = job.id;

-- 2. 查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
/*
    分析:
            1. 员工编号,员工姓名,工资在emp表中
            2. 职务名称,职务描述 在job中
            3. job表和emp表 是1:N联系 条件:emp.job_id = job.id

            4. 部门名称,部门位置在dept表,dept表和emp表是1:N 条件:dept.id = emp.dept_id
*/
-- 隐式内连接
SELECT
    emp.id,
    emp.ename,
    emp.salary,
    job.jname,
    job.description,
    dept.dname,
    dept.loc
FROM
    emp,
    job,
    dept
WHERE
    emp.job_id = job.id
  AND
  dept.id = emp.dept_id;

-- 显式内连接
SELECT
    emp.id,
    emp.ename,
    emp.salary,
    job.jname,
    job.description,
    dept.dname,
    dept.loc
FROM
    emp
INNER JOIN job ON emp.job_id = job.id
INNER JOIN dept ON dept.id = emp.dept_id;


-- 3. 查询员工姓名,工资,工资等级
/*
    分析:
            1. 员工编号,员工姓名,工资在emp表中
            2. 工资等级 在salarygrade中
            3. emp.salary >= salarygrade.lowsalary and emp.salary <= salarygrade.highsalary
*/
SELECT emp.id, emp.ename, t2.grade FROM emp , salarygrade t2 WHERE emp.salary >= t2.lowsalary and emp.salary <= t2.highsalary

SELECT emp.id, emp.ename, t2.grade FROM emp , salarygrade t2 WHERE emp.salary BETWEEN t2.lowsalary and t2.highsalary;

-- 4. 查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
/*
    分析:
            1. 员工编号,员工姓名,工资在emp表中
            2. 职务名称,职务描述 在job中
            3. job表和emp表 是1:N联系 条件:emp.job_id = job.id
            4. 部门名称,部门位置在dept表,dept表和emp表是1:N 条件:dept.id = emp.dept_id
            5. 工资等级在salarygrade 表
            6.  emp.salary >= salarygrade.lowsalary and emp.salary <= salarygrade.highsalary
*/
-- 隐式内连接
SELECT
    emp.id,
    emp.ename,
    emp.salary,
    job.jname,
    job.description,
    dept.dname,
    dept.loc,
    salarygrade.grade
FROM
    emp,
    job,
    dept,
    salarygrade t2
WHERE
    emp.job_id = job.id
  AND
  dept.id = emp.dept_id
    AND
    emp.salary >= t2.lowsalary and emp.salary <= t2.highsalary;


-- 显式内连接
SELECT
    emp.id,
    emp.ename,
    emp.salary,
    job.jname,
    job.description,
    dept.dname,
    dept.loc
  t2.grade
FROM
    emp
INNER JOIN job ON emp.job_id = job.id
INNER JOIN dept ON dept.id = emp.dept_id
INNER JOIN salarygrade t2 ON  emp.salary BETWEEN t2.lowsalary and t2.highsalary;


-- 5. 查询部门编号,部门名称,部门位置,部门人数
/*
    分析:
            1. 部门编号,部门名称,部门位置 来自于部门dept
            2. 部门人数:在emp表 按照dept_id 进行分组,然后count(*)统计数量
            3. 使用子查询,让部门表和分组后的表进行内连接
*/
SELECT * FROM dept;

SELECT dept_id, COUNT(*) FROM emp GROUP BY dept_id;


SELECT
    dept.id,
    dept.dname,
    dept.loc,
    t1.count
FROM
    dept,
    (
        SELECT
            dept_id,
            COUNT(*) count
        FROM
            emp
        GROUP BY
            dept_id
    ) t1
WHERE
    dept.id = t1.dept_id;

事务

数据库事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。

事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即要么同时成功,要么同时失败

事务是一个不可分割的工作逻辑单元。

-- 转账事务 =================
DROP TABLE IF EXISTS account;

-- 账户表
CREATE TABLE account (
    id INT PRIMARY KEY auto_increment,
    name VARCHAR(10),
    money DOUBLE(10,2)
);

-- 添加数据
INSERT INTO account(name,money) VALUES
('张三',1000),('李四',1000);

SELECT * FROM account;

-- 转账操作 =========

-- 开启事务
BEGIN;
-- 1. 查询李四的余额

-- 2. 李四账户 -500
UPDATE account set money = money - 500 WHERE name='李四';
-- 出错了....


-- 3. 张三账户 +500
UPDATE account set money = money + 500 WHERE name='张三';

-- 提交事务
COMMIT;

-- 回滚事务
ROLLBACK;
 

-- 1. 查询事务的默认提交方式
SELECT @@autocommit;
SET @@autocommit = 0;

-- 2. 李四的金额 -500 
UPDATE account set money = money - 500 WHERE name='李四';

-- COMMIT;
COMMIT;
 

常见的面试题

简述事务的四大特征:

  • 原子性(Atomocty):事务是不可分割的最小操作单位,要么同时成功,要么同时失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(Isolation):多个事务之间,操作的可见性,
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

注:MySQL事务默认自动提交

-- 查看事务的默认提交方式

select @@autocommit;

-- 修改事务提交方式

-- 1 自动提交, 0 手动提交

set @@autocommit = 0;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/168682
推荐阅读
相关标签
  

闽ICP备14008679号