MySql基础

1. 数据库概述

什么是数据库?什么是数据库管理系统?什么是SQL?它们之间的关系是什么?

数据库

​ DataBase,简称:DB。按照一定格式存储数据的一些文件的组合。

​ 顾名思义:存储数据的仓库,实际上就是一推文件。这些文件中存储了具有特定格式的数据。

数据库管理系统

​ DataBaseManagement,简称:DBMS。

​ 数据库管理系统是专门用来管理数据库中的数据的,数据库管理系统可以对数据库当中的数据进行增删改查。

​ 常见的数据库管理系统:

​ mysql、Oracle、MS sqlserver、DB2、sybase等等

SQL:结构化查询语言

​ 程序员需要学习sql语句,程序员通过编写sql语句,然后DBMS负责执行sql语句,最终来完成数据库中数据增删改查操作。

三者之间的关系?

​ DBMS–执行 ----> SQL --> 操作 ---->DB

2. 安装数据库管理系统

  1. 先安装
  2. 需要进行mysql数据库实例配置
  3. 傻瓜式安装

需要注意事项:

端口号:

    • 端口号port是任何一个软件/应用都会有的,端口号是应用中的唯一代表。
    • 端口号通常和ip地址在一块,ip地址用来定位计算机的,端口号port是用来定位计算机某一个服务/应用
    • 在同一台计算机上,端口号不能重复,具有唯一性

mysql数据库启动时侯,这个服务占有的默认端口是3306

字符编码方式?

设置mysql数据库的字符编码为UTF8

mysql超级管理员用户名不能改,一定是root

3. mysql服务暂停

语法:net stop 服务名称;

​ net start 服务名称;

其他服务的启停都可以使用以上命令。

4. 登录mysql

使用bin目录下的mysql.exe命令连接mysql数据库服务器

本地登录(显示密码):

D:\Code\Mysql>mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.39-log MySQL Community Server (GPL)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>

本地登录(隐藏密码):

D:\Code\Mysql>mysql -uroot -p
Enter password: ****
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.39-log MySQL Community Server (GPL)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

5. mysql常用命令

  1. 退出mysql:exit
  2. 查看mysql有哪些数据库? show databases; mysql默认自带了4个数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db02               |
| db03               |
| db_value           |
| mysql              |
| performance_schema |
| sakila             |
| sys                |
| world              |
+--------------------+
9 rows in set (0.00 sec)
  1. 怎么选择使用某个数据库?
mysql> use db02;
Database changed
# 正在使用db02的数据库
  1. 创建数据库

    mysql> create database test;
    Query OK, 1 row affected (0.03 sec)
    
    
    
  2. 查看数据库有哪些表? show tables;

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | db02               |
    | db03               |
    | db_value           |
    | mysql              |
    | performance_schema |
    | sakila             |
    | sys                |
    | test               |
    | world              |
    +--------------------+
    10 rows in set (0.00 sec)
    
  3. 导入表

mysql> source D:\Code\Mysql\bjpowernode.sql
Query OK, 0 rows affected (0.20 sec)

Query OK, 0 rows affected (0.19 sec)

Query OK, 0 rows affected (0.17 sec)

Query OK, 0 rows affected (0.35 sec)

Query OK, 0 rows affected (0.26 sec)

Query OK, 0 rows affected (0.25 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.09 sec)

Query OK, 1 row affected (0.07 sec)

Query OK, 1 row affected (0.07 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected (0.05 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.05 sec)

Query OK, 1 row affected (0.05 sec)

Query OK, 1 row affected (0.05 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.02 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.02 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.05 sec)

Query OK, 1 row affected (0.05 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected (0.03 sec)

Query OK, 1 row affected (0.05 sec)

Query OK, 1 row affected (0.11 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 1 row affected (0.04 sec)

Query OK, 0 rows affected (0.00 sec)
  1. 查看表
mysql> show tables;
+--------------------+
| Tables_in_practice |
+--------------------+
| dept               |
| emp                |
| salgrade           |
+--------------------+
3 rows in set (0.00 sec)

# dept 是部门表
# emp是员工表
# salgrade是工资等级表
  1. 查看表里的数据
select * from 表名;
# 部门表
mysql> select * from dept;     -- 从dept表查询所有数据
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.01 sec)

# 员工表
mysql> select * from emp;    -- 从emp表查询所有数据
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.01 sec)


# 工资等级表
mysql> select * from salgrade;     -- 从salgrade表查询所有数据
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
|     1 |   700 |  1200 |
|     2 |  1201 |  1400 |
|     3 |  1401 |  2000 |
|     4 |  2001 |  3000 |
|     5 |  3001 |  9999 |
+-------+-------+-------+
5 rows in set (0.00 sec)
  1. 查看mysql数据版本

    mysql> select version();
    +------------+
    | version()  |
    +------------+
    | 5.7.39-log |
    +------------+
    1 row in set (0.06 sec)
    
  2. 查看当前使用的数据库

    mysql> select database();
    +------------+
    | database() |
    +------------+
    | practice   |
    +------------+
    1 row in set (0.00 sec)
    
  3. Mysql不见分号不执行

    mysql> show
        -> databases
        -> ;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | db02               |
    | db03               |
    | db_value           |
    | mysql              |
    | performance_schema |
    | practice           |
    | sakila             |
    | sys                |
    | test               |
    | world              |
    +--------------------+
    11 rows in set (0.00 sec)
    
  4. \c终止执行

    mysql> show
        ->
        ->
        -> \c
    

6. 表的理解

数据库当中最基本的单元是表:table

什么是表?为什么用来存储数据?

姓名	性别	年龄(列:字段)
张三	男		20                            ------> 行 (记录)

数据库当中是以表格的形式表示数据

任何一张表都有行和列:

​ 行(row):被称为数据/记录

​ 列(column):被称为字段

每一个字段都有L字段名、数据类型、约束等属性

字段名可理解为:是一个普通名字

数据类型:字符串、数字、日期等

约束:有很多。其中一个叫唯一性约束。这种约束添加之后,该字段中的数据不能重复。

7. SQL的分类

SQL语句分类

7.1. DQL数据查询语言

​ select 带有select关键字都是查询语句

7.2. DML数据操作语言

对表里的数据进行操作:

​ insert 增

​ delete 删

​ update 改

7.3. DDL

带有create、drop、alter

对表的结构进行操作

​ create 新建等同于 增

​ drop 删除

​ alter 修改

这个增删改与DML不同,这个主要对表的结构操作

7.4. TCL事务控制语言

事务提交:commit

事务回滚:rollback

7.5. DCL数据控制语言

​ 授权 grant、撤销权限revoke

8. 导入数据

mysql> source D:\Code\Mysql\databases.sql           #  路径不要有中文

9. 查看表结构

desc 表名
mysql> use practice;
Database changed
mysql> desc emp;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| EMPNO    | int(4)      | NO   | PRI | NULL    |       |员工编号
| ENAME    | varchar(10) | YES  |     | NULL    |       |员工姓名
| JOB      | varchar(9)  | YES  |     | NULL    |       |工作岗位
| MGR      | int(4)      | YES  |     | NULL    |       |上级编号
| HIREDATE | date        | YES  |     | NULL    |       |入职日期
| SAL      | double(7,2) | YES  |     | NULL    |       |工资
| COMM     | double(7,2) | YES  |     | NULL    |       |补助
| DEPTNO   | int(2)      | YES  |     | NULL    |       |部门编号
+----------+-------------+------+-----+---------+-------+
8 rows in set (0.04 sec)

mysql> desc dept;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| DEPTNO | int(2)      | NO   | PRI | NULL    |       |部门编号
| DNAME  | varchar(14) | YES  |     | NULL    |       |部门名字
| LOC    | varchar(13) | YES  |     | NULL    |       |地理位置
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)


mysql> desc salgrade;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| GRADE | int(11) | YES  |     | NULL    |       |工资等级
| LOSAL | int(11) | YES  |     | NULL    |       |最低工资
| HISAL | int(11) | YES  |     | NULL    |       |最高工资
+-------+---------+------+-----+---------+-------+
3 rows in set (0.01 sec)

10. 简单查询 from

10.1. 查询一个字段

select 字段名 from 表名;
# 注意:select和from都是关键字
# 	   字段名和表名都是标识符

mysql> select dname from dept;
+------------+
| dname      |
+------------+
| ACCOUNTING |
| RESEARCH   |
| SALES      |
| OPERATIONS |
+------------+
4 rows in set (0.00 sec)

10.2. 查询多个字段

使用逗号隔开

# select 字段名1,字段名2 from 表名;
mysql> select deptno,dname from dept;
+--------+------------+
| deptno | dname      |
+--------+------------+
|     10 | ACCOUNTING |
|     20 | RESEARCH   |
|     30 | SALES      |
|     40 | OPERATIONS |
+--------+------------+
4 rows in set (0.00 sec)

10.3. 查询所有字段

#  select * from 表名;   -- * 代表所有
mysql> select * from emp;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)

10.4. 查询列起别名

# select 字段名1,字段名2 as 别名名称 from 表名;     -- as 关键字 起别名   as也可以省略不写
mysql> select deptno,dname as deptname from dept;
+--------+------------+
| deptno | deptname   |
+--------+------------+
|     10 | ACCOUNTING |
|     20 | RESEARCH   |
|     30 | SALES      |
|     40 | OPERATIONS |
+--------+------------+
4 rows in set (0.10 sec)


# as关键字也可省略不写
mysql> select deptno,dname  deptname from dept;
+--------+------------+
| deptno | deptname   |
+--------+------------+
|     10 | ACCOUNTING |
|     20 | RESEARCH   |
|     30 | SALES      |
|     40 | OPERATIONS |
+--------+------------+
4 rows in set (0.00 sec)

10.5. 列的数学运算

mysql> select ename,sal from emp; -- 查看员工名字和工资
+--------+---------+
| ename  | sal     |
+--------+---------+
| SMITH  |  800.00 |
| ALLEN  | 1600.00 |
| WARD   | 1250.00 |
| JONES  | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| SCOTT  | 3000.00 |
| KING   | 5000.00 |
| TURNER | 1500.00 |
| ADAMS  | 1100.00 |
| JAMES  |  950.00 |
| FORD   | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+

# 运算员工的年薪           字段可以使用数学表达式
mysql> select ename,sal*12 as 'annual salary' from emp;
+--------+---------------+
| ename  | annual salary |
+--------+---------------+
| SMITH  |       9600.00 |
| ALLEN  |      19200.00 |
| WARD   |      15000.00 |
| JONES  |      35700.00 |
| MARTIN |      15000.00 |
| BLAKE  |      34200.00 |
| CLARK  |      29400.00 |
| SCOTT  |      36000.00 |
| KING   |      60000.00 |
| TURNER |      18000.00 |
| ADAMS  |      13200.00 |
| JAMES  |      11400.00 |
| FORD   |      36000.00 |
| MILLER |      15600.00 |
+--------+---------------+

11. 条件查询 where

11.1. 语法格式

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

11.2. 条件

运算符 说明
= 等于
<>或 != 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
between…and, 两个值之间,等同于 >= and <=
is null 为bull(is not null不为空)
and 并且
or 或者
in 包含,相当于多个or(not in不在或者范围)
not not可以取非,主要用在is或in中
like like称为模糊查询,支持%或者下划线匹配,%匹配任意一个字符,一个下划线只能匹配一个字符
mysql> select empno,ename from emp where sal = 800;      -- 查询薪资等于800的员工姓名和编号
+-------+-------+
| empno | ename |
+-------+-------+
|  7369 | SMITH |
+-------+-------+
1 row in set (0.32 sec)

mysql> select empno,ename from emp where sal != 800;      -- 查询薪资不等于800的员工姓名和编号
+-------+--------+
| empno | ename  |
+-------+--------+
|  7499 | ALLEN  |
|  7521 | WARD   |
|  7566 | JONES  |
|  7654 | MARTIN |
|  7698 | BLAKE  |
|  7782 | CLARK  |
|  7788 | SCOTT  |
|  7839 | KING   |
|  7844 | TURNER |
|  7876 | ADAMS  |
|  7900 | JAMES  |
|  7902 | FORD   |
|  7934 | MILLER |
+-------+--------+
13 rows in set (0.31 sec)

mysql> select empno,ename from emp where sal <> 800;      -- 查询薪资不等于800的员工姓名和编号
+-------+--------+
| empno | ename  |
+-------+--------+
|  7499 | ALLEN  |
|  7521 | WARD   |
|  7566 | JONES  |
|  7654 | MARTIN |
|  7698 | BLAKE  |
|  7782 | CLARK  |
|  7788 | SCOTT  |
|  7839 | KING   |
|  7844 | TURNER |
|  7876 | ADAMS  |
|  7900 | JAMES  |
|  7902 | FORD   |
|  7934 | MILLER |
+-------+--------+
13 rows in set (0.00 sec)


mysql> select empno,ename,sal from emp where sal < 2000;       -- 查询薪资小于2000的员工姓名和编号
+-------+--------+---------+
| empno | ename  | sal     |
+-------+--------+---------+
|  7369 | SMITH  |  800.00 |
|  7499 | ALLEN  | 1600.00 |
|  7521 | WARD   | 1250.00 |
|  7654 | MARTIN | 1250.00 |
|  7844 | TURNER | 1500.00 |
|  7876 | ADAMS  | 1100.00 |
|  7900 | JAMES  |  950.00 |
|  7934 | MILLER | 1300.00 |
+-------+--------+---------+
8 rows in set (0.00 sec)


-- 查询薪资小于等于2000的员工姓名和编号
mysql> select empno,ename,sal from emp where sal <= 2000;
+-------+--------+---------+
| empno | ename  | sal     |
+-------+--------+---------+
|  7369 | SMITH  |  800.00 |
|  7499 | ALLEN  | 1600.00 |
|  7521 | WARD   | 1250.00 |
|  7654 | MARTIN | 1250.00 |
|  7844 | TURNER | 1500.00 |
|  7876 | ADAMS  | 1100.00 |
|  7900 | JAMES  |  950.00 |
|  7934 | MILLER | 1300.00 |
+-------+--------+---------+
8 rows in set (0.00 sec)

-- 查询薪资大于3500的员工姓名和编号
mysql> select empno,ename,sal from emp where sal > 3500;
+-------+-------+---------+
| empno | ename | sal     |
+-------+-------+---------+
|  7839 | KING  | 5000.00 |
+-------+-------+---------+
1 row in set (0.00 sec)
-- 查询薪资大于等于3000的员工姓名和编号
mysql> select empno,ename,sal from emp where sal >= 3000;
+-------+-------+---------+
| empno | ename | sal     |
+-------+-------+---------+
|  7788 | SCOTT | 3000.00 |
|  7839 | KING  | 5000.00 |
|  7902 | FORD  | 3000.00 |
+-------+-------+---------+
3 rows in set (0.00 sec)

-- 查询薪资在2450和3000之间的员工信息
mysql> select * from emp where sal between 2450 and 3000;    between ... and...  左闭右闭
+-------+-------+---------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB     | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+---------+------+------------+---------+------+--------+
|  7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
|  7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL |     30 |
|  7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL |     10 |
|  7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
|  7902 | FORD  | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
+-------+-------+---------+------+------------+---------+------+--------+
5 rows in set (0.30 sec)


-- 查询那些员工的津贴或者补助为null
mysql> select empno,ename,comm from emp where comm is null;
+-------+--------+------+
| empno | ename  | comm |
+-------+--------+------+
|  7369 | SMITH  | NULL |
|  7566 | JONES  | NULL |
|  7698 | BLAKE  | NULL |
|  7782 | CLARK  | NULL |
|  7788 | SCOTT  | NULL |
|  7839 | KING   | NULL |
|  7876 | ADAMS  | NULL |
|  7900 | JAMES  | NULL |
|  7902 | FORD   | NULL |
|  7934 | MILLER | NULL |
+-------+--------+------+
10 rows in set (0.00 sec)


-- 查询那些员工的津贴或者补助不为null
mysql> select empno,ename,comm from emp where comm is not null;
+-------+--------+---------+
| empno | ename  | comm    |
+-------+--------+---------+
|  7499 | ALLEN  |  300.00 |
|  7521 | WARD   |  500.00 |
|  7654 | MARTIN | 1400.00 |
|  7844 | TURNER |    0.00 |
+-------+--------+---------+
4 rows in set (0.00 sec)


-- 查询工作岗位是MANGER并且薪水>2500
mysql> select empno,ename,job,sal
    ->          from emp
    ->          where job = 'MANAGER' and sal > 2500;
+-------+-------+---------+---------+
| empno | ename | job     | sal     |
+-------+-------+---------+---------+
|  7566 | JONES | MANAGER | 2975.00 |
|  7698 | BLAKE | MANAGER | 2850.00 |
+-------+-------+---------+---------+
2 rows in set (0.00 sec)

-- 查询工作岗位是MANGER和SALESMAN的员工
mysql> select empno,ename,job from emp where job = 'MANAGER';
+-------+-------+---------+
| empno | ename | job     |
+-------+-------+---------+
|  7566 | JONES | MANAGER |
|  7698 | BLAKE | MANAGER |
|  7782 | CLARK | MANAGER |
+-------+-------+---------+
3 rows in set (0.00 sec)

mysql> select empno,ename,job from emp where job = 'MANAGER' or job = 'salesman';
+-------+--------+----------+
| empno | ename  | job      |
+-------+--------+----------+
|  7499 | ALLEN  | SALESMAN |
|  7521 | WARD   | SALESMAN |
|  7566 | JONES  | MANAGER  |
|  7654 | MARTIN | SALESMAN |
|  7698 | BLAKE  | MANAGER  |
|  7782 | CLARK  | MANAGER  |
|  7844 | TURNER | SALESMAN |
+-------+--------+----------+
7 rows in set (0.00 sec)

-- and优先级比or优先级高
-- 找出工资大于2500并且部门编号为10的员工,或者20部门的所有员工
mysql> select * from emp where sal > 2500 and (deptno = 10 or deptno = 20);
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB       | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7566 | JONES | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
|  7788 | SCOTT | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
|  7902 | FORD  | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
+-------+-------+-----------+------+------------+---------+------+--------+
4 rows in set (0.00 sec)

-- 查询工作岗位是MANAGER和SALESMAN的员工
mysql> select * from emp where job in('MANAGER','SALESMAN');
+-------+--------+----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB      | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+----------+------+------------+---------+---------+--------+
|  7499 | ALLEN  | SALESMAN | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
|  7521 | WARD   | SALESMAN | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7566 | JONES  | MANAGER  | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
|  7698 | BLAKE  | MANAGER  | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER  | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
+-------+--------+----------+------+------------+---------+---------+--------+
7 rows in set (0.00 sec)

-- 模糊查询
-- 找出名字里有‘o’的员工信息
mysql> select * from emp where ename like '%o%';
+-------+-------+---------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB     | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+---------+------+------------+---------+------+--------+
|  7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
|  7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
|  7902 | FORD  | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
+-------+-------+---------+------+------------+---------+------+--------+
3 rows in set (0.00 sec)
-- 找出名字以‘T’结尾的
mysql> select * from emp where ename like '%T';
+-------+-------+---------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB     | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+---------+------+------------+---------+------+--------+
|  7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
+-------+-------+---------+------+------------+---------+------+--------+
1 row in set (0.00 sec)
-- 找出名字以‘k’开始的
mysql> select * from emp where ename like 'K%';
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB       | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
+-------+-------+-----------+------+------------+---------+------+--------+
1 row in set (0.00 sec)
-- 找出名字第二个字母是A的
mysql> select ename from emp where ename like '_A%';
+--------+
| ename  |
+--------+
| WARD   |
| MARTIN |
| JAMES  |
+--------+
3 rows in set (0.00 sec)



-- 找出名字里有“_”
mysql> select * from t_student where name like '%\_%';
+----------+
| name     |
+----------+
| jack_son |
+----------+
1 row in set (0.00 sec)

12. 排序 order by

12.1. 查询所有员工工资,升序 asc

# 默认是升序     
mysql> select ename,sal from emp order by sal;
+--------+---------+
| ename  | sal     |
+--------+---------+
| SMITH  |  800.00 |
| JAMES  |  950.00 |
| ADAMS  | 1100.00 |
| WARD   | 1250.00 |
| MARTIN | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN  | 1600.00 |
| CLARK  | 2450.00 |
| BLAKE  | 2850.00 |
| JONES  | 2975.00 |
| SCOTT  | 3000.00 |
| FORD   | 3000.00 |
| KING   | 5000.00 |
+--------+---------+
14 rows in set (0.11 sec)

12.2. 降序 desc

mysql> select ename,sal from emp order by sal desc;
+--------+---------+
| ename  | sal     |
+--------+---------+
| KING   | 5000.00 |
| SCOTT  | 3000.00 |
| FORD   | 3000.00 |
| JONES  | 2975.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| ALLEN  | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| WARD   | 1250.00 |
| MARTIN | 1250.00 |
| ADAMS  | 1100.00 |
| JAMES  |  950.00 |
| SMITH  |  800.00 |
+--------+---------+
14 rows in set (0.00 sec)

12.3. 多个字段排序

查询员工名字和薪资,要求按照薪资升序,如果薪资一样的话,再按照名字升序排列

mysql> select ename,sal from emp order by sal asc,ename asc;
+--------+---------+
| ename  | sal     |
+--------+---------+
| SMITH  |  800.00 |
| JAMES  |  950.00 |
| ADAMS  | 1100.00 |
| MARTIN | 1250.00 |
| WARD   | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN  | 1600.00 |
| CLARK  | 2450.00 |
| BLAKE  | 2850.00 |
| JONES  | 2975.00 |
| FORD   | 3000.00 |
| SCOTT  | 3000.00 |
| KING   | 5000.00 |
+--------+---------+
14 rows in set (0.00 sec)

12.4. 综合案列

关键字顺序不能改变,最后一步是排序

select * from emp where sal between 1250 and 3000 order by sal desc;
select 
	...
from
	...
where
	...
order by
	...

# 找出工资在1250到3000之间的员工信息,要求按照薪资降序排列

mysql> select * from emp where sal between 1250 and 3000 order by sal desc;
+-------+--------+----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB      | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+----------+------+------------+---------+---------+--------+
|  7788 | SCOTT  | ANALYST  | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
|  7902 | FORD   | ANALYST  | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
|  7566 | JONES  | MANAGER  | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7698 | BLAKE  | MANAGER  | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER  | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7499 | ALLEN  | SALESMAN | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
|  7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
|  7934 | MILLER | CLERK    | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
|  7521 | WARD   | SALESMAN | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
+-------+--------+----------+------+------------+---------+---------+--------+
10 rows in set (0.00 sec)

13. 数据处理函数 / 单行分组查询

数据处理函数又被称为单行处理函数

单行处理函数的特点:一个输入对应一个输出

和单行处理函数相对的是:多行处理函数(多行处理函数的特点:多个输入对应一个输出)

函数名称 解释
lower 转换小写
upper 转换大写
substr 取子串(substr[被截取的字符串,其实下标,截取的长度])
length 取长度
trim 去空格
str_to_date 将字符串转换成日期
date_format 格式化日期
format 设置千分位
round 四舍五入
rand() 生成随机数
Ifnull() 可以将null转换成一个具体值
case…when…then…when…then…else…end 当…时,… 当…时,…
mysql> select lower(ename) from emp;          -- 转换小写
+--------------+
| lower(ename) |
+--------------+
| smith        |
| allen        |
| ward         |
| jones        |
| martin       |
| blake        |
| clark        |
| scott        |
| king         |
| turner       |
| adams        |
| james        |
| ford         |
| miller       |
+--------------+
14 rows in set (0.00 sec)

mysql> select * from t_student;            
+----------+
| name     |
+----------+
| zhangsan |
| lisi     |
| wangwu   |
| jack     |
| jack_son |
+----------+
5 rows in set (0.00 sec)

mysql> select upper(name) from t_student;			-- 转换大写
+-------------+
| upper(name) |
+-------------+
| ZHANGSAN    |
| LISI        |
| WANGWU      |
| JACK        |
| JACK_SON    |
+-------------+
5 rows in set (0.00 sec)

mysql> select substr(ename,1,3) from emp;			-- 截取字符串
+-------------------+
| substr(ename,1,3) |
+-------------------+
| SMI               |
| ALL               |
| WAR               |
| JON               |
| MAR               |
| BLA               |
| CLA               |
| SCO               |
| KIN               |
| TUR               |
| ADA               |
| JAM               |
| FOR               |
| MIL               |
+-------------------+
14 rows in set (0.00 sec)



# 首字母大写
upper(substr(name,1,1)             -- 取首字母再转换为大写
substr(name,2,length(name) - 1))   -- 取其余字母
concat()                           -- 连接
mysql> select concat(upper(substr(name,1,1)),substr(name,2,length(name) - 1)) as result from t_student;
+----------+
| result   |
+----------+
| Zhangsan |
| Lisi     |
| Wangwu   |
| Jack     |
| Jack_son |
+----------+
5 rows in set (0.00 sec)


# 取长度
mysql> select ename,length(ename) namelength from emp;
+--------+------------+
| ename  | namelength |
+--------+------------+
| SMITH  |          5 |
| ALLEN  |          5 |
| WARD   |          4 |
| JONES  |          5 |
| MARTIN |          6 |
| BLAKE  |          5 |
| CLARK  |          5 |
| SCOTT  |          5 |
| KING   |          4 |
| TURNER |          6 |
| ADAMS  |          5 |
| JAMES  |          5 |
| FORD   |          4 |
| MILLER |          6 |
+--------+------------+
14 rows in set (0.00 sec)


# 去空格
mysql> select * from emp where ename = trim('   KING');
+-------+-------+-----------+------+------------+---------+------+--------+
| EMPNO | ENAME | JOB       | MGR  | HIREDATE   | SAL     | COMM | DEPTNO |
+-------+-------+-----------+------+------------+---------+------+--------+
|  7839 | KING  | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
+-------+-------+-----------+------+------------+---------+------+--------+
1 row in set (0.00 sec)

#  四舍五入 、 随机数
mysql>  select rand() from emp;
+---------------------+
| rand()              |
+---------------------+
| 0.20973383934212275 |
| 0.23245041745943057 |
|  0.5330506000044296 |
|  0.9679017783775011 |
| 0.24035712260786177 |
| 0.29808030864045054 |
|  0.7693302061123124 |
|  0.9524101353738551 |
|  0.4540600892659836 |
| 0.41307007094199777 |
|  0.7031701176456828 |
|  0.2766404061360661 |
| 0.27369170847692686 |
|   0.538537354710081 |
+---------------------+
14 rows in set (0.13 sec)

mysql>  select round(rand()*10) from emp;
+------------------+
| round(rand()*10) |
+------------------+
|                9 |
|                7 |
|                1 |
|                3 |
|                0 |
|                3 |
|                2 |
|                4 |
|                5 |
|                0 |
|                8 |
|                8 |
|                5 |
|                0 |
+------------------+
14 rows in set (0.00 sec)

mysql>  select round(rand()*100) from emp;
+-------------------+
| round(rand()*100) |
+-------------------+
|                80 |
|                88 |
|                99 |
|                32 |
|                63 |
|                21 |
|                16 |
|                14 |
|                23 |
|                75 |
|                 4 |
|                95 |
|                64 |
|                35 |
+-------------------+
14 rows in set (0.00 sec)


# ifnull是空函数
# 在所有数据中,只要有null参与的数学运算,最终结果就是null
mysql> select ename,sal + comm as salcomm from emp;
+--------+---------+
| ename  | salcomm |
+--------+---------+
| SMITH  |    NULL |
| ALLEN  | 1900.00 |
| WARD   | 1750.00 |
| JONES  |    NULL |
| MARTIN | 2650.00 |
| BLAKE  |    NULL |
| CLARK  |    NULL |
| SCOTT  |    NULL |
| KING   |    NULL |
| TURNER | 1500.00 |
| ADAMS  |    NULL |
| JAMES  |    NULL |
| FORD   |    NULL |
| MILLER |    NULL |
+--------+---------+
14 rows in set (0.00 sec)


# 计算每个员工的年薪
#  年薪 = (月薪 + 补助) * 12
# null 只要参与运算,最终结果一定是null。为避免结果为null,需使用ifnull函数
# ifnull函数用法:ifnull(数据,被替换的值)
mysql> select ename,(sal + ifnull(comm,0)) * 12 as yearsal from emp;
+--------+----------+
| ename  | yearsal  |
+--------+----------+
| SMITH  |  9600.00 |
| ALLEN  | 22800.00 |
| WARD   | 21000.00 |
| JONES  | 35700.00 |
| MARTIN | 31800.00 |
| BLAKE  | 34200.00 |
| CLARK  | 29400.00 |
| SCOTT  | 36000.00 |
| KING   | 60000.00 |
| TURNER | 18000.00 |
| ADAMS  | 13200.00 |
| JAMES  | 11400.00 |
| FORD   | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+
14 rows in set (0.00 sec)


# 当员工的工作岗位时MANAGER的时候,工资上调10%,当工作岗位时SALESMAN的时候,工资上调50%
mysql> select ename,job,sal,(case job when 'MANAGER' then sal*1.1 when 'SALESMAN' then sal*1.5 else sal end) as yearsal from emp;
+--------+-----------+---------+---------+
| ename  | job       | sal     | yearsal |
+--------+-----------+---------+---------+
| SMITH  | CLERK     |  800.00 |  800.00 |
| ALLEN  | SALESMAN  | 1600.00 | 2400.00 |
| WARD   | SALESMAN  | 1250.00 | 1875.00 |
| JONES  | MANAGER   | 2975.00 | 3272.50 |
| MARTIN | SALESMAN  | 1250.00 | 1875.00 |
| BLAKE  | MANAGER   | 2850.00 | 3135.00 |
| CLARK  | MANAGER   | 2450.00 | 2695.00 |
| SCOTT  | ANALYST   | 3000.00 | 3000.00 |
| KING   | PRESIDENT | 5000.00 | 5000.00 |
| TURNER | SALESMAN  | 1500.00 | 2250.00 |
| ADAMS  | CLERK     | 1100.00 | 1100.00 |
| JAMES  | CLERK     |  950.00 |  950.00 |
| FORD   | ANALYST   | 3000.00 | 3000.00 |
| MILLER | CLERK     | 1300.00 | 1300.00 |
+--------+-----------+---------+---------+
14 rows in set (0.00 sec)

14. 分组函数(多行处理函数)

多行处理函数的特点:输入多行,输出一行

5个函数:

  1. count 计数
  2. sum 求和
  3. avg 平均值
  4. max 最大值
  5. min 最小值

注意:分组函数在使用的时候必须先进行分组,然后才能使用。如果你每页对数据进行分组,整张表默认为一组

# 最高工资
mysql> select ename,max(sal) from emp;
+-------+----------+
| ename | max(sal) |
+-------+----------+
| SMITH |  5000.00 |
+-------+----------+
1 row in set (0.08 sec)
# 最低工资
mysql> select ename,min(sal) from emp;
+-------+----------+
| ename | min(sal) |
+-------+----------+
| SMITH |   800.00 |
+-------+----------+
1 row in set (0.00 sec)
# 平均工资
mysql> select ename,avg(sal) from emp;
+-------+-------------+
| ename | avg(sal)    |
+-------+-------------+
| SMITH | 2073.214286 |
+-------+-------------+
1 row in set (0.10 sec)
# 计算员工数量
mysql> select count(ename) from emp;
+--------------+
| count(ename) |
+--------------+
|           14 |
+--------------+
1 row in set (0.00 sec)

分组函数在使用的时候需要注意哪些?

mysql> select sum(comm) from emp;
+-----------+
| sum(comm) |
+-----------+
|   2200.00 |
+-----------+
1 row in set (0.00 sec)

# 1、分组函数字段忽略null,不需要提前对null及进行处理


# 2、分组函数count(*)和count(具体字段)有什么区别?
mysql> select count(*) from emp;
+----------+
| count(*) |
+----------+
|       14 |
+----------+
1 row in set (0.09 sec)

mysql> select count(comm) from emp;
+-------------+
| count(comm) |
+-------------+
|           4 |
+-------------+
1 row in set (0.00 sec)


# count(具体字段):表示统计该字段下所有不为null的元素的总数
# count(*):统计表当中的总行数(只要有一行数据count则++)



# 3、分组函数不能直接使用在where子句中
mysql> select ename,sal from emp where sal > min(sal);
ERROR 1111 (HY000): Invalid use of group function

# 4、所有的分组函数可以组合一起使用
mysql> select sum(sal),min(sal),max(sal),count(*) from emp;
+----------+----------+----------+----------+
| sum(sal) | min(sal) | max(sal) | count(*) |
+----------+----------+----------+----------+
| 29025.00 |   800.00 |  5000.00 |       14 |
+----------+----------+----------+----------+
1 row in set (0.00 sec)

15. 分组查询 group by

15.1. 执行顺序

select
	...
from
	...
group by
	...
order by
	...

以上执行顺序:

  1. from
  2. where
  3. group by
  4. select
  5. order by

为什么分组函数不能直接使用在where后面?

​ select ename,sal from emp where sal > min (sal); // 报错

​ 因为分组函数在使用的时候必须分组之后才能使用。

​ where执行的时候,还没有分组,所以where后面不能出现分组函数

​ select sum(sal) from emp; 这个没有分组,为啥sum()函数可以使用?

​ 因为select在group by 之后执行。

计算每个部门的工资和

mysql> select deptno,sum(sal) from emp group by deptno;
+--------+----------+
| deptno | sum(sal) |
+--------+----------+
|     10 |  8750.00 |
|     20 | 10875.00 |
|     30 |  9400.00 |
+--------+----------+
3 rows in set (0.00 sec)

计算每个工作岗位的平均薪资

mysql> select job,avg(sal) from emp group by job;
+-----------+-------------+
| job       | avg(sal)    |
+-----------+-------------+
| ANALYST   | 3000.000000 |
| CLERK     | 1037.500000 |
| MANAGER   | 2758.333333 |
| PRESIDENT | 5000.000000 |
| SALESMAN  | 1400.000000 |
+-----------+-------------+
5 rows in set (0.00 sec)

计算每个工作岗位的最大

mysql> select job,max(sal) from emp group by job;
+-----------+----------+
| job       | max(sal) |
+-----------+----------+
| ANALYST   |  3000.00 |
| CLERK     |  1300.00 |
| MANAGER   |  2975.00 |
| PRESIDENT |  5000.00 |
| SALESMAN  |  1600.00 |
+-----------+----------+
5 rows in set (0.00 sec)

15.2. 找出每个工作岗位的分组,然后对工资求和

mysql> select job ,sum(sal) from emp group by job;
+-----------+----------+
| job       | sum(sal) |
+-----------+----------+
| ANALYST   |  6000.00 |
| CLERK     |  4150.00 |
| MANAGER   |  8275.00 |
| PRESIDENT |  5000.00 |
| SALESMAN  |  5600.00 |
+-----------+----------+
5 rows in set (0.00 sec)

# 执行顺序
# 先从emp表中查询数据,根据job字段及进行分组,然后对每一组的数据进行sum(sal)

重点结论:

​ 在一条select 语句当中,如果有group by语句的话,select 后面只能跟:参加分组的字段,以及分虚函数。其他的一律不能跟。

15.3. 找出每个部门的最高薪资

实现思路:按照部门编号,求出每一组的最大值

mysql> select ename,deptno,max(sal) from emp group by deptno;
+-------+--------+----------+
| ename | deptno | max(sal) |
+-------+--------+----------+
| CLARK |     10 |  5000.00 |
| SMITH |     20 |  3000.00 |
| ALLEN |     30 |  2850.00 |
+-------+--------+----------+
3 rows in set (0.00 sec)	




# 找出每个部门,不同工作岗位的最高薪资?
mysql> select deptno,job,max(sal) from emp group by deptno,job;
+--------+-----------+----------+
| deptno | job       | max(sal) |
+--------+-----------+----------+
|     10 | CLERK     |  1300.00 |
|     10 | MANAGER   |  2450.00 |
|     10 | PRESIDENT |  5000.00 |
|     20 | ANALYST   |  3000.00 |
|     20 | CLERK     |  1100.00 |
|     20 | MANAGER   |  2975.00 |
|     30 | CLERK     |   950.00 |
|     30 | MANAGER   |  2850.00 |
|     30 | SALESMAN  |  1600.00 |
+--------+-----------+----------+
9 rows in set (0.00 sec)

15.4. 使用having可以对分完组之后的数据进一步过滤,having必须和group by联合使用

每个部门最高薪资且最高薪资大于3000

  1. 找出部门最高薪资,按照部门编号分组,求出每一组最大
mysql> select deptno,max(sal) from emp group by deptno;
+--------+----------+
| deptno | max(sal) |
+--------+----------+
|     10 |  5000.00 |
|     20 |  3000.00 |
|     30 |  2850.00 |
+--------+----------+
3 rows in set (0.00 sec)
  1. 要求显示最高薪资大于3000

    mysql> select deptno,max(sal) from emp group by deptno having max(sal) > 3000;
    +--------+----------+
    | deptno | max(sal) |
    +--------+----------+
    |     10 |  5000.00 |
    +--------+----------+
    1 row in set (0.00 sec)
    \
    
    
    mysql> select deptno,max(sal) from emp where sal > 3000 group by deptno;
    +--------+----------+
    | deptno | max(sal) |
    +--------+----------+
    |     10 |  5000.00 |
    +--------+----------+
    1 row in set (0.00 sec)
    

    优化策略:where和having,优先选择where,where实在完成不了,再选择having

    15.5. where选不了

    找出每个部门平均薪资,要求显示平均薪资高于2000

    mysql> select deptno,avg(sal) as avgsal from emp group by deptno having avgsal > 2500;
    +--------+-------------+
    | deptno | avgsal      |
    +--------+-------------+
    |     10 | 2916.666667 |
    +--------+-------------+
    1 row in set (0.00 sec)
    

    16. 单表查询总结

    select 
    	...
    from
    	...
    group by
    	...
    having
    	...
    order by
    	...
    

    执行顺序

    1. from
    2. where
    3. group by
    4. having
    5. select
    6. order by

    找出每个岗位的平均薪资,要求显示平均薪资大于1500的,除MANAGER岗位之外,要求按照平均薪资降序排列

mysql> select job,avg(sal)
    -> from emp
    -> where job != 'MANAGER'
    -> group by job
    -> having avg(sal) > 1500
    -> order by avg(sal) desc;
+-----------+-------------+
| job       | avg(sal)    |
+-----------+-------------+
| PRESIDENT | 5000.000000 |
| ANALYST   | 3000.000000 |
+-----------+-------------+
2 rows in set (0.00 sec)

16. 多表查询

16.1. 去除重复记录 distinct

查询结果去重,注意:原表数据不会被修改,只是查询结果去重,去重关键字:distinct

mysql> select job from emp;
+-----------+
| job       |
+-----------+
| CLERK     |
| SALESMAN  |
| SALESMAN  |
| MANAGER   |
| SALESMAN  |
| MANAGER   |
| MANAGER   |
| ANALYST   |
| PRESIDENT |
| SALESMAN  |
| CLERK     |
| CLERK     |
| ANALYST   |
| CLERK     |
+-----------+
14 rows in set (0.01 sec)

mysql> select distinct job from emp;
+-----------+
| job       |
+-----------+
| CLERK     |
| SALESMAN  |
| MANAGER   |
| ANALYST   |
| PRESIDENT |
+-----------+
5 rows in set (0.00 sec)

统计工作岗位的数量

mysql> select count(distinct job) from emp;
+---------------------+
| count(distinct job) |
+---------------------+
|                   5 |
+---------------------+
1 row in set (0.18 sec)

16.2. 连接查询

跨表查询,多张表联合起来查询数据,被称为连接查询

根据语法查询的分类:

  1. SQL92:1992年的时候出现的语法
  2. SQL99:1999年的时候出现的语法

根据表连接的方式分类:

  1. 内连接
    1. 等值连接
    2. 非等值连接
    3. 自连接
  2. 外连接
    1. 左外连接(左连接)
    2. 右外连接(右连接)
  3. 全连接(不常用)

16.3. 怎么避免笛卡尔积现象

当两张表进行连接查询时,没有任何条件限制的时候,最终查询结果条数,时两张表条数的乘积,这种现象被称为:笛卡尔积现象

mysql> select ename,dname from emp,dept where emp.deptno = dept.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)

注意:通过笛卡尔积现象得出,表的连接次数越多效率越低,尽量避免表的连接次数

16.4. 内连接之等值连接

查询每个员工所在部门名称

emp表和dept表进行连接。条件是:emp.deptno = dept.deptno

SQL92语法:

select
	ename,dname
from
	emp,dept
where
	emp.deptno = dept.deptno

SQL92语法缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面

SQL99语法:

# inner 可省略
select
	ename,dname
from
	a
inner join          -- 连接
	b
on			 -- a和b的连接条件
	emp.deptno = dept.deptno

SQL99优点:表连接的条件时独立的,连接之后,如果还需要进一步筛选,再往后继续添加where

16.5. 内连接之非等值连接

找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?

mysql> select ename,sal,grade 
	   from emp 
	   join salgrade 
	   on emp.sal 
	   between salgrade.losal and salgrade.hisal;            -- 条件不是一个等量关系,称为非等值连接
+--------+---------+-------+
| ename  | sal     | grade |
+--------+---------+-------+
| SMITH  |  800.00 |     1 |
| ALLEN  | 1600.00 |     3 |
| WARD   | 1250.00 |     2 |
| JONES  | 2975.00 |     4 |
| MARTIN | 1250.00 |     2 |
| BLAKE  | 2850.00 |     4 |
| CLARK  | 2450.00 |     4 |
| SCOTT  | 3000.00 |     4 |
| KING   | 5000.00 |     5 |
| TURNER | 1500.00 |     3 |
| ADAMS  | 1100.00 |     1 |
| JAMES  |  950.00 |     1 |
| FORD   | 3000.00 |     4 |
| MILLER | 1300.00 |     2 |
+--------+---------+-------+
14 rows in set (0.00 sec)

16.6. 内连接之自连接

查询员工的上级领导,要求显示员工名和对应的领导名

select 
	a.ename as '员工名',b.ename as '领导名'
from
	emp a
join
	emp b
on
	a.mgr = b.empno;


mysql> select y.ename as 'yname',l.ename as 'lname' from emp y join emp l on y.mgr = l.empno;
+--------+-------+
| yname  | lname |
+--------+-------+
| SMITH  | FORD  |
| ALLEN  | BLAKE |
| WARD   | BLAKE |
| JONES  | KING  |
| MARTIN | BLAKE |
| BLAKE  | KING  |
| CLARK  | KING  |
| SCOTT  | JONES |
| TURNER | BLAKE |
| ADAMS  | SCOTT |
| JAMES  | BLAKE |
| FORD   | JONES |
| MILLER | CLARK |
+--------+-------+
13 rows in set (0.00 sec)

以上就是内连接中的:自连接,技巧:一张表看作两张表

16.7. 外连接

# 员工表
mysql> select * from emp;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)
# 部门表
mysql> select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
4 rows in set (0.00 sec)
# 内连接:   特点:完全能够匹配上这个条件的数据查询出来
mysql> select a.ename,b.dname from emp a join dept b on a.deptno = b.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)


# 外连接[右外连接]:right关键字表示将join关键字右边的这张表看成主表,主要为了将这张表的数据全部查询出来,捎带着关联查询左边的表
mysql> select a.ename,b.dname
    ->  from emp a
    ->  right join dept b
    ->  on a.deptno = b.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
| NULL   | OPERATIONS |
+--------+------------+
15 rows in set (0.00 sec)


# 外连接[左外连接]:right关键字表示将join关键字左边的这张表看成主表,主要为了将这张表的数据全部查询出来,捎带着关联查询右边的表
mysql> select a.ename,b.dname
    ->  from dept b
    ->  right join emp a
    ->  on a.deptno = b.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
| NULL   | OPERATIONS |
+--------+------------+
15 rows in set (0.00 sec)

带有right的时右外连接,又叫做右连接

带有left的时左外连接,又叫做左连接

查询每个员工的上级领导,要求显示所有员工的名字和领导名?

mysql> select a.ename as '员工',b.ename as '领导' from emp a left join emp b
    -> on  a.mgr = b.empno;
+--------+-------+
| 员工   | 领导  |
+--------+-------+
| SMITH  | FORD  |
| ALLEN  | BLAKE |
| WARD   | BLAKE |
| JONES  | KING  |
| MARTIN | BLAKE |
| BLAKE  | KING  |
| CLARK  | KING  |
| SCOTT  | JONES |
| KING   | NULL  |
| TURNER | BLAKE |
| ADAMS  | SCOTT |
| JAMES  | BLAKE |
| FORD   | JONES |
| MILLER | CLARK |
+--------+-------+
14 rows in set (0.00 sec)

16.8. 三张表或多张表查询

select
	...
from
	a
join
	b
on
	a和b的连接条件
join
	c
on
	a和c的连接条件
join
	d
on
	a和d的连接条件

一条SQL中内连接和外连接可以混合出现

16.9. 综合案例

找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级?

mysql> select e.ename,d.dname,e.sal,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal;
+--------+------------+---------+-------+
| ename  | dname      | sal     | grade |
+--------+------------+---------+-------+
| SMITH  | RESEARCH   |  800.00 |     1 |
| ALLEN  | SALES      | 1600.00 |     3 |
| WARD   | SALES      | 1250.00 |     2 |
| JONES  | RESEARCH   | 2975.00 |     4 |
| MARTIN | SALES      | 1250.00 |     2 |
| BLAKE  | SALES      | 2850.00 |     4 |
| CLARK  | ACCOUNTING | 2450.00 |     4 |
| SCOTT  | RESEARCH   | 3000.00 |     4 |
| KING   | ACCOUNTING | 5000.00 |     5 |
| TURNER | SALES      | 1500.00 |     3 |
| ADAMS  | RESEARCH   | 1100.00 |     1 |
| JAMES  | SALES      |  950.00 |     1 |
| FORD   | RESEARCH   | 3000.00 |     4 |
| MILLER | ACCOUNTING | 1300.00 |     2 |
+--------+------------+---------+-------+
14 rows in set (0.00 sec)

mysql> select e.ename,d.dname,e.sal,s.grade from emp e right join dept d on e.deptno = d.deptno right join salgrade s on e.sal between s.losal and s.hisal; 
+--------+------------+---------+-------+
| ename  | dname      | sal     | grade |
+--------+------------+---------+-------+
| SMITH  | RESEARCH   |  800.00 |     1 |
| ADAMS  | RESEARCH   | 1100.00 |     1 |
| JAMES  | SALES      |  950.00 |     1 |
| WARD   | SALES      | 1250.00 |     2 |
| MARTIN | SALES      | 1250.00 |     2 |
| MILLER | ACCOUNTING | 1300.00 |     2 |
| ALLEN  | SALES      | 1600.00 |     3 |
| TURNER | SALES      | 1500.00 |     3 |
| JONES  | RESEARCH   | 2975.00 |     4 |
| BLAKE  | SALES      | 2850.00 |     4 |
| CLARK  | ACCOUNTING | 2450.00 |     4 |
| SCOTT  | RESEARCH   | 3000.00 |     4 |
| FORD   | RESEARCH   | 3000.00 |     4 |
| KING   | ACCOUNTING | 5000.00 |     5 |
+--------+------------+---------+-------+
14 rows in set (0.00 sec) 

17. 子查询

17.1. 什么是子查询?

select语句中嵌套select语句,被嵌套的select语句称为子查询

17.2. 子查询出现的地方

select
	...(select)
from 
	...(select)
where
	...(select)

17.3. where子句中的子查询

案例:找出比最低工资高的员工姓名和工资

mysql> select ename,sal
    -> from emp
    -> where sal > (select min(sal)
    -> from emp);
+--------+---------+
| ename  | sal     |
+--------+---------+
| ALLEN  | 1600.00 |
| WARD   | 1250.00 |
| JONES  | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| SCOTT  | 3000.00 |
| KING   | 5000.00 |
| TURNER | 1500.00 |
| ADAMS  | 1100.00 |
| JAMES  |  950.00 |
| FORD   | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
13 rows in set (0.00 sec)

17.3. from子句中的子查询

注意:from后面的子查询,可以将子查询的查询结果当作一张临时表

案例:找出每个岗位的平均工资的薪资等级

select job,avg(sal) as salavg from emp group by job;

select
	t.*,s.grade
from (select job,avg(sal) as salavg from emp group by job) t-- avg(sal) 带有关键字系统会认为它是一个分组函数,必须起别名
join salgrade s
on t.salavg between s.losal and s.hisal;             -- avg(sal) 带有关键字系统会认为它是一个分组函数,必须起别名

mysql> select
    ->  t.*,s.grade
    -> from (select job,avg(sal) as salavg from emp group by job) t
    -> join salgrade s
    -> on t.salavg between s.losal and s.hisal;
+-----------+-------------+-------+
| job       | salavg      | grade |
+-----------+-------------+-------+
| ANALYST   | 3000.000000 |     4 |
| CLERK     | 1037.500000 |     1 |
| MANAGER   | 2758.333333 |     4 |
| PRESIDENT | 5000.000000 |     5 |
| SALESMAN  | 1400.000000 |     2 |
+-----------+-------------+-------+
5 rows in set (0.00 sec)

17.3. select子句中的子查询

案例:找出每个员工的部门名称,显示部门名和员工名

mysql> select e.ename,e.deptno,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
+--------+--------+------------+
| ename  | deptno | dname      |
+--------+--------+------------+
| SMITH  |     20 | RESEARCH   |
| ALLEN  |     30 | SALES      |
| WARD   |     30 | SALES      |
| JONES  |     20 | RESEARCH   |
| MARTIN |     30 | SALES      |
| BLAKE  |     30 | SALES      |
| CLARK  |     10 | ACCOUNTING |
| SCOTT  |     20 | RESEARCH   |
| KING   |     10 | ACCOUNTING |
| TURNER |     30 | SALES      |
| ADAMS  |     20 | RESEARCH   |
| JAMES  |     30 | SALES      |
| FORD   |     20 | RESEARCH   |
| MILLER |     10 | ACCOUNTING |
+--------+--------+------------+
14 rows in set (0.00 sec)

注意:对于select后面的子查询来说,这个子查询只能一次返回一条结果,多于一条,就报错

18. union 合并查询结果集

案例:查询工作岗位时MANAGER和SALESMAN的员工?

mysql> select ename,job from emp where job in('MANAGER','SALESMAN');
+--------+----------+
| ename  | job      |
+--------+----------+
| ALLEN  | SALESMAN |
| WARD   | SALESMAN |
| JONES  | MANAGER  |
| MARTIN | SALESMAN |
| BLAKE  | MANAGER  |
| CLARK  | MANAGER  |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)

mysql> select ename,job from emp where job = 'MANAGER'
    -> union
    ->  select ename,job from emp where job = 'SALESMAN';
+--------+----------+
| ename  | job      |
+--------+----------+
| JONES  | MANAGER  |
| BLAKE  | MANAGER  |
| CLARK  | MANAGER  |
| ALLEN  | SALESMAN |
| WARD   | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)

union的效率要高一些。对于表连接来说,每连接一次新表,则匹配的次数满足笛卡尔积,成倍翻。

但是union可以减少匹配的次数。在减少匹配的次数的情况下,还可以完成两个结果集的拼接

union注意事项:

  1. union在进行结果集合并的时候,要求两个结果集的列数相同
    2.MySql基础_第1张图片

19. limit

19.1. 什么是limit

limit是将查询结果集的一部分取出来,通常使用在分页查询当中

19.1. limit的使用

limit完整用法:limit startIndex,length

startIndex 是起始下标,length是长度

起始下标从0开始

案例:按照薪资降序,取出排名在前5名的员工?

mysql> select ename,sal from emp order by sal desc limit 5;
+-------+---------+
| ename | sal     |
+-------+---------+
| KING  | 5000.00 |
| FORD  | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.00 sec)

注意:mysql当中limit在order by之后执行

取出工资排名在[5-9]名的员工

mysql> select
    ->  ename,sal
    -> from
    ->  emp
    -> order by
    ->  sal desc
    -> limit
    ->  4,5;
+--------+---------+
| ename  | sal     |
+--------+---------+
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| ALLEN  | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
+--------+---------+
5 rows in set (0.00 sec)

19.3. 通用分页

每页显示3条记录

第一页:limit [0,3] [0 1 2]

第二页:limit [3,3] [3 4 5]

第三页:limit [6,3] [6 7 8]

第四页:limit [9,3] [9 10 11]

每页显示pagesize条记录

​ 第pageNo页:limit (页数 - 1) * 记录数

记公式:limit (pageNo - 1)*pageSize,pageSize

MySql基础_第2张图片

20. DQL语句大总结

select
	...
from
	...
group by                  -- 分组
	...
having					-- 过滤
	...
order by				-- 排序
	...
limit					-- 分页
	...
	
	
# 执行顺序
	1from	
	2where
	3group by
	4having
	5select
	6order by
	7limit

21. 表

21.1. 创建表

创建表语法格式:(创建表属于DDL语句,DDL包括(create drop alter))

create table 表名(
	字段名1 数据类型;
    字段名2 数据类型;
    字段名3 数据类型;
);

create table t_movies(
	no bigint,
    name varchar(255),
    description clob,
    playtime date,
    times time,
    image blob,
    type char
); 
mysql> create table t_student(No int,name varchar(32),sex char(1),age int(3),email varchar(255));
Query OK, 0 rows affected (0.60 sec)

mysql> desc t_student;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| No    | int(11)      | YES  |     | NULL    |       |
| name  | varchar(32)  | YES  |     | NULL    |       |
| sex   | char(1)      | YES  |     | NULL    |       |
| age   | int(3)       | YES  |     | NULL    |       |
| email | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

表名:建议以t_或者 tbl_ 开始,可读性强。建名知意

字段名:建名知意

表名和字段名都属于标识符

21.2. 常见数据类型

数据类型 中文解释
varchar(最长255) 可变长度的字符串,会根据数据长度分配空间
char(最长255) 固定长度字符串
int(最长11) 数字中的长整型
bigint 数字中的长整型
float 单精度浮点型
double 双精度浮点型
date 短日期类型
datetime 长日期类型
clob(最长255) 字符大对象,最多可以存储4G的字符串。例如:存储一篇文章或说明。超过255个字符都要使用CLOB字符大对象来存储。 Character Large Object:CLOB
blob(最长255) 二进制大对象。Binary Large Object 专门用来存储图片、声音、视频等流媒体数据。往BLOB类型的字段插入数据时,例如:插入一张图片、视频等,你需要使用IO流才可以

21.3. 插入语句 insert[DML语句]

语法格式: insert into 表名 (字段名1,字段名2,字段名3,…) values(值1,值2,值3);

注意:字段名和值要一一对应

mysql> insert into t_student(no,name,sex,age,email) values(1,'zhangsan','m','20','[email protected]');
Query OK, 1 row affected (0.37 sec)

mysql> select * from t_student;
+------+----------+------+------+------------------+
| No   | name     | sex  | age  | email            |
+------+----------+------+------+------------------+
|    1 | zhangsan | m    |   20 | zhangsan@123.com |
+------+----------+------+------+------------------+
1 row in set (0.00 sec)

注意:insert语句但凡是执行成功了,必然会多一条记录。每页给其他指定值的话,默认就是NULL

21.3.1. insert 插入多条记录
mysql> insert into t_student values(1,'qiliu','m',26,'[email protected]'),(3,'jiuqi','m',21,'[email protected]');
Query OK, 2 rows affected (0.16 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t_student;
+------+----------+------+------+------------------+
| No   | name     | sex  | age  | email            |
+------+----------+------+------+------------------+
|    1 | zhangsan | m    |   20 | zhangsan@123.com |
| NULL | NULL     | NULL | NULL | NULL             |
|    1 | qiliu    | m    |   26 | qiliu@123.com    |
|    3 | jiuqi    | m    |   21 | jiuqi@123.com    |
+------+----------+------+------+------------------+
4 rows in set (0.00 sec)

21.4. 插入日期

数字格式化:format(数字,‘格式’)

mysql> select ename,format(sal,',') as sal from emp;
+--------+-------+
| ename  | sal   |
+--------+-------+
| SMITH  | 800   |
| ALLEN  | 1,600 |
| WARD   | 1,250 |
| JONES  | 2,975 |
| MARTIN | 1,250 |
| BLAKE  | 2,850 |
| CLARK  | 2,450 |
| SCOTT  | 3,000 |
| KING   | 5,000 |
| TURNER | 1,500 |
| ADAMS  | 1,100 |
| JAMES  | 950   |
| FORD   | 3,000 |
| MILLER | 1,300 |
+--------+-------+
14 rows in set, 14 warnings (0.00 sec)

21.5. 字符串转日期,格式化日期

str_to_date:将字符串varchar类型转换成date类型

str_to_date函数可以把字符串varchar转换成日期date类型数据,通常使用在插入insert方面,因为的插入需要一个日期类型的数据,需要通过该函数将字符转换成date

%Y  年
%m  月
%d	日
%d	时
%i	分
%s	秒
mysql> insert into t_user values(2,'wangwu',str_to_date('1995-10-3','%Y-%m-%d'));
Query OK, 1 row affected (0.38 sec)

mysql> select * from t_user;
+------+--------+------------+
| id   | name   | birth      |
+------+--------+------------+
|    1 | zhaosi | 1999-09-23 |
|    2 | wangwu | 1995-10-03 |
+------+--------+------------+
2 rows in set (0.00 sec)

date_format:将date类型转换成具有一定格式的varchar类型

date_format函数可以将日期类型转换成特定格式的字符串

date_format(日期类型数据, ‘日期格式’)这个函数通常使用在查询日期方面。设置展示的日期格式

mysql> select id,name,date_format(birth,'%m/%d/%Y') as birth from t_user;
+------+--------+------------+
| id   | name   | birth      |
+------+--------+------------+
|    1 | zhaosi | 09/23/1999 |
|    2 | wangwu | 10/03/1995 |
+------+--------+------------+
2 rows in set (0.00 sec)

注意:数据库中命名规范:所有的标识符都是小写,单词之间使用下划线链接

21.6. date和datetime的区别

date是短日期:只包括年月日信息

datetime是长日期:包括年月日时分秒信息

获取当前时间:now()函数

mysql> insert into t_user values(2,'liliu','1999-09-9',now());
Query OK, 1 row affected (0.13 sec)

mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1999-09-09 | 2022-10-08 17:20:33 |
|    2 | liliu    | 1999-09-09 | 2022-10-16 17:22:48 |
+------+----------+------------+---------------------+
2 rows in set (0.00 sec)

21.7. update修改(更新)语句[DML]

**语法格式: **

update 表名  set 字段名1 =1,字段名2 =2,字段名3 =3... where 条件

注意:没有条件限制会导致所有全部更新

mysql> update t_user set name = 'laohu',birth = '1995-10-20' where id = 2;
Query OK, 1 row affected (0.46 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t_user;
+------+----------+------------+---------------------+
| id   | name     | birth      | create_time         |
+------+----------+------------+---------------------+
|    1 | zhangsan | 1999-09-09 | 2022-10-08 17:20:33 |
|    2 | laohu    | 1995-10-20 | 2022-10-16 17:22:48 |
+------+----------+------------+---------------------+
2 rows in set (0.00 sec)

21.8. delete删除语句[DML]

语法格式:

delete from 表名 where 条件

注意:没有条件,整张表数据都会删除

mysql> select * from t_user;
+------+-------+------------+---------------------+
| id   | name  | birth      | create_time         |
+------+-------+------------+---------------------+
|    2 | laohu | 1995-10-20 | 2022-10-16 17:37:12 |
+------+-------+------------+---------------------+
1 row in set (0.00 sec)
delete from t_user                           -- s

21.9. 快速复制表[快速创建表]

mysql> create table emp2 as select * from emp;
Query OK, 14 rows affected (0.52 sec)
Records: 14  Duplicates: 0  Warnings: 0

mysql> show tables;
+--------------------+
| Tables_in_practice |
+--------------------+
| dept               |
| emp                |
| emp2               |
| salgrade           |
| t_student          |
| t_user             |
+--------------------+
6 rows in set (0.00 sec)

mysql> select * from emp2;
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME  | JOB       | MGR  | HIREDATE   | SAL     | COMM    | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 |  800.00 |    NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    0.00 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.00 sec)

原理:将一个查询结果当作一张表新建,可以快速完成表的复制,同时表中数据也保存了

21.10. 将查询结果插入一张表

mysql> select * from mytable;
+-------+-------+
| empno | ename |
+-------+-------+
|  7566 | JONES |
|  7698 | BLAKE |
|  7782 | CLARK |
+-------+-------+
3 rows in set (0.00 sec)

将查询结果插入到一张表中 insert相关【了解】

mysql> insert into dept_bak select * from dept;
Query OK, 4 rows affected (0.05 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from dept_bak;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
8 rows in set (0.00 sec)

21.11. 快速删除表的数据

// 删除dept_bak表中的数据
delete from dept_bak; // 这种删除数据的方式比较慢

delete语句删除数据的原理?【DML】

表中的数据被删除了,但是这个数据再硬盘上的真是存储空间不会被释放。**缺点:**删除效率比较低 **优点:**支持回滚,可以恢复数据

truncate语句删除数据的原理:效率高,表被一次截断,物理删除。缺点:不支持回滚 优点:快速 【DDL】

truncate table dept_bak;

表数据非常大:删除时,使用delete需要1小时左右才能删除完,效率低 ==可以使用truncate:==删除表中数据。效率高。但是使用truncate之前,必须仔细询问客户是否真的要删除,并警告删除之后不可恢复

删除表操作

drop table 表名;  // 这不是删除表中的数据,删除整个表

21.12. 对表的结构的增删改

MySql基础_第3张图片

21.13. 约束

21.13.1 约束 constraint

在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中的数据完整性和有效性

约束的作用:为了保证表中的数据有效

21.13.2. 约束有哪些
非空约束 not null
唯一性约束 unique
主键约束 primary key【简称PK】
外键约束 foreign key【简称FK】
检查约束 check(mysql不支持,Oracle支持)
21.13.2.1. 非空约束 not null

非空约束not null约束的字段不能为NULL

mysql> drop table if exists t_vip;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create table t_vip(id int,name varchar(255) not null);
Query OK, 0 rows affected (0.74 sec)

mysql> insert into t_vip values(1,'zhangsan');
Query OK, 1 row affected (0.40 sec)

mysql>  insert into t_vip values(2,'lisi');
Query OK, 1 row affected (0.14 sec)

xxx.sql这种文件被称为sql脚本文件。

sql脚本文件中编写了大量的sql语句

我们执行sql脚本文件的时候,该文件中所有的sql语句会全部执行

批量的执行sql语句,可以使用sql脚本文件

再mysql中怎么执行sql脚本? mysql> source D:/Code/Mysql/vip.sql

21.13.2.1. 唯一性约束 unique

唯一性约束unique约束的字段不能重复,但是可以为NULL

mysql> drop table if exists t_vip;
Query OK, 0 rows affected (0.62 sec)

mysql> create table t_vip(
    -> id int,
    ->     name varchar(255) unique,                         // -- 约束直接添加到列后面,叫做列级约束
    ->     email varchar(255)
    -> );
Query OK, 0 rows affected (0.48 sec)

mysql> insert into t_vip values(1,'zhangsan','[email protected]');
Query OK, 1 row affected (0.15 sec)

mysql> insert into t_vip values(2,'wangwu','[email protected]');
Query OK, 1 row affected (0.04 sec)

mysql> insert into t_vip values(3,'liuzi','[email protected]');
Query OK, 1 row affected (0.14 sec)

mysql> select * from t_vip;
+------+----------+------------------+
| id   | name     | email            |
+------+----------+------------------+
|    1 | zhangsan | zhangsan@123.com |
|    2 | wangwu   | wangwu@123.com   |
|    3 | liuzi    | liuzi@123.com    |
+------+----------+------------------+
3 rows in set (0.00 sec)


21.13.2.2.两个字段联合唯一

需求:name和email两个字段联合起来具有唯一性

drop table if exists t_vip;
create table t_vip( 
	id int,
    name varchar(255),
    email vaarchar(255),
    unique(name,email)                         // -- 约束没有添加再列的后面,这种约束称为表级约束
);

什么时候使用表级约束?

需要给多个字段联合起来添加某一个约束的时候,需要使用表级约束

21.13.2.13.not null 和 unique联合
drop table if exists t_vip;
create table t_vip(
	id int,
    name varchar(255) not null unique
);

在mysql当中,如果一个字段同时被not null和unique约束的话,该字段自动变成字段【Oracle不一样】

21.14. 主键约束 【primary key】

21.14. 1. 概述

在这里插入图片描述

主键:主键值时每一行记录的唯一标识

主键值时每一行记录的身份证号

主键的特征:not null + unique(主键值不能是NULL,同时也不能重复)

21.14. 2. 怎么给一张表添加主键约束?
drop table if exists t_vip;
create table t_vip(
	id int primary key,
    name varchar(255)
);
insert into t_vip values(1,'zhangsan');
insert into t_vip values(2,'wangsi');
insert into t_vip values(3,'liudai');


mysql> create table t_vip(
    -> id int primary key,
    ->     name varchar(255)
    -> );
Query OK, 0 rows affected (0.26 sec)

mysql> insert into t_vip values(1,'zhangsan');
Query OK, 1 row affected (0.04 sec)

mysql> insert into t_vip values(2,'wangsi');
Query OK, 1 row affected (0.04 sec)

mysql> insert into t_vip values(3,'liudai');
Query OK, 1 row affected (0.06 sec)

mysql> select * from t_vip;
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | wangsi   |
|  3 | liudai   |
+----+----------+
3 rows in set (0.00 sec)


mysql> insert into t_vip values(4,'li');
Query OK, 1 row affected (0.09 sec)
21.14. 3. 表级约束主要是给多个字段联合起来添加约束?
drop table if exists t_vip;
// id 和 name联合起来左主键:复合主键
create table t_vip(
	id int,
    name varchar(255),
    email varchar(255),
    primary key(id,name)
);
insert into t_vip values(1,'zhangsan','[email protected]');
insert into t_vip values(2,'liuliu','[email protected]');
insert into t_vip values(3,'wangliu','[email protected]');

在实际开发中不建议使用:复合主键。建议使用单一主键

**因为主键值存在的意义就是这行记录的身份证号,只要意义达到即可,单一主键可以做到。复合主键比较复杂,不建议使用 **

21.14. 4. 主键值建议使用

int、bingint、char等类型。

不建议使用:varchar来做主键。主键值一般都是数字,都是定长的

21.14. 5. 自然主键和业务主键

主键除了:单一主键和复合主键之外,还可以这样进行分类?

自然主键:主键值是一个自然数,和业务没关系

业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。

在实际开发中使用业务主键多,还是使用自然主键多一些?

自然主键使用比较多,因为主键只要做到不重复就行,不需要有意义

y讹误主键不好,因为主键一旦和业务挂钩,那么当业务发生变动时,可能会影响到主键值,所以业务主键不建议使用。尽量使用自然主键

drop table if exists t_vip;
create table t_vip(
	id int primary key auto_increment,				-- auto_increment 自增
    name varchar(255)
);
insert into t_vip(name) values('zhangsan'),('wangliu'),('likui');
21.14. 6. 外键约束【foreign key】

外键约束涉及到相关术语:

​ 外键约束:一种约束(foreign key)

​ 外键字段:该字段上添加了外键约束

​ 外键值:外键字段当中的每一个 值

MySql基础_第4张图片
MySql基础_第5张图片

mysql> create table t_student(
    ->     no int primary key auto_increment,         -- no做主键,no自增
    ->     name varchar(255),
    ->     cno int,									-- 班级编号
    ->     foreign key(cno) references t_class(classno));	-- t_student表的cno做t_class表的外键
Query OK, 0 rows affected (0.46 sec)

在这里插入图片描述

22. 存储引擎

22.1. 存储引擎概念及作用

存储引擎是MySQL中特有的一个术语,其他数据库中没有(Oracle中有,但名字不一样)

实际上存储引擎是一个表存储/组织数据的方式

不同的存储引擎,表存储数据的方式不同

22.2. 添加/指定“存储引擎”

show create table t_student;

可以在建表的时候给表指定存储引擎

 t_student | CREATE TABLE `t_student` (
  `no` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `cno` int(11) DEFAULT NULL,
  PRIMARY KEY (`no`),
  KEY `cno` (`cno`),
  CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1               -- ENGINE=InnoDB DEFAULT CHARSET=latin1  存储引擎

在建表的时候可以在最后小括号的右边使用:ENGINE来指定存储引擎 ,CHARSET来指定表的字符编码方式

mysql> create table t_product(id int primary key,name varchar(255))engine=inndb default charset=utf8;
ERROR 1286 (42000): Unknown storage engine 'inndb'
mysql> create table t_product(id int primary key,name varchar(255))engine=InnoDB default charset=utf8;
Query OK, 0 rows affected (0.63 sec)

mysql> show create table t_product;
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                      |
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------+
| t_product | CREATE TABLE `t_product` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

22.3. 查看MySQL支持哪些存储引擎

mysql> show engines \G;
*************************** 1. row ***************************
      Engine: InnoDB
     Support: DEFAULT
     Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 2. row ***************************
      Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 4. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 5. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 8. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 9. row ***************************
      Engine: FEDERATED
     Support: NO
     Comment: Federated MySQL storage engine
Transactions: NULL
          XA: NULL
  Savepoints: NULL
9 rows in set (0.00 sec)

22.4. 常见存储引擎

MyISAM存储引擎

MySql基础_第6张图片

InnoDB存储引擎
MySql基础_第7张图片

MEMORY存储引擎
MySql基础_第8张图片

23. 事务

23.1. 事务概念

一个事务就是一个完整的业务逻辑

**一个完整的业务逻辑:**假设转账,从A账户向B账户转账10000,将A账户的钱减去10000【update语句】,将B账户的钱加上10000【update语句】,这就是业务逻辑。

在这里插入图片描述

23.2. 只有DML语句才会有事务一说。

insert、delete、update只有这三个语句和事务有关,其他语句都没有关系【对数据库表中的数据进行增、删、改】

23.3. 对事务的理解

一个事务就是多条DML语句同时成功,或者同时失败

23.4. 实现事务

MySql基础_第9张图片

23.5. 提交和回滚事务

MySql基础_第10张图片

23.6. 事务的四大特性

MySql基础_第11张图片

23.7. 事务的隔离性

MySql基础_第12张图片

MySql基础_第13张图片

23.8. 事务隔离级别演示

MySql基础_第14张图片
MySql基础_第15张图片
MySql基础_第16张图片

MySql基础_第17张图片

MySql基础_第18张图片

24. 索引

24.1. 索引概念

MySql基础_第19张图片
MySql基础_第20张图片

24.2. 索引实现原理

MySql基础_第21张图片

理解

MySql基础_第22张图片

24.3. 主键及unique字段都会自动添加索引

MySql基础_第23张图片

24.4. 索引语法、创建、删除

创建索引

mysql> create index emp_ename_index on emp(ename);
//  给emp表的ename字段添加索引,起名为:emp_ename_index

删除索引

mysql> drop index emp_ename_index on emp;
//  给emp表的ename字段删除索引对象删除

查看sql语句是否使用索引进行检索

mysql> explain select * from emp where ename = 'KING';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   14 |    10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.02 sec)

24.5. 索引失效的情况

  1. MySql基础_第24张图片

  2. 在这里插入图片描述

  3. MySql基础_第25张图片

  4. MySql基础_第26张图片

  5. MySql基础_第27张图片

24.6. 索引的分类

MySql基础_第28张图片

你可能感兴趣的:(MYSQL基础,mysql,数据库,sqlserver)