什么是数据库?什么是数据库管理系统?什么是SQL?它们之间的关系是什么?
数据库:
DataBase,简称:DB。按照一定格式存储数据的一些文件的组合。
顾名思义:存储数据的仓库,实际上就是一推文件。这些文件中存储了具有特定格式的数据。
数据库管理系统:
DataBaseManagement,简称:DBMS。
数据库管理系统是专门用来管理数据库中的数据的,数据库管理系统可以对数据库当中的数据进行增删改查。
常见的数据库管理系统:
mysql、Oracle、MS sqlserver、DB2、sybase等等
SQL:结构化查询语言
程序员需要学习sql语句,程序员通过编写sql语句,然后DBMS负责执行sql语句,最终来完成数据库中数据增删改查操作。
三者之间的关系?
DBMS–执行 ----> SQL --> 操作 ---->DB
需要注意事项:
端口号:
mysql数据库启动时侯,这个服务占有的默认端口是3306
字符编码方式?
设置mysql数据库的字符编码为UTF8
mysql超级管理员用户名不能改,一定是root
语法:net stop 服务名称;
net start 服务名称;
其他服务的启停都可以使用以上命令。
使用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>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db02 |
| db03 |
| db_value |
| mysql |
| performance_schema |
| sakila |
| sys |
| world |
+--------------------+
9 rows in set (0.00 sec)
mysql> use db02;
Database changed
# 正在使用db02的数据库
创建数据库
mysql> create database test;
Query OK, 1 row affected (0.03 sec)
查看数据库有哪些表? 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)
导入表
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)
mysql> show tables;
+--------------------+
| Tables_in_practice |
+--------------------+
| dept |
| emp |
| salgrade |
+--------------------+
3 rows in set (0.00 sec)
# dept 是部门表
# emp是员工表
# salgrade是工资等级表
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)
查看mysql数据版本
mysql> select version();
+------------+
| version() |
+------------+
| 5.7.39-log |
+------------+
1 row in set (0.06 sec)
查看当前使用的数据库
mysql> select database();
+------------+
| database() |
+------------+
| practice |
+------------+
1 row in set (0.00 sec)
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)
\c终止执行
mysql> show
->
->
-> \c
数据库当中最基本的单元是表:table
什么是表?为什么用来存储数据?
姓名 性别 年龄(列:字段)
张三 男 20 ------> 行 (记录)
数据库当中是以表格的形式表示数据
任何一张表都有行和列:
行(row):被称为数据/记录
列(column):被称为字段
每一个字段都有L字段名、数据类型、约束等属性
字段名可理解为:是一个普通名字
数据类型:字符串、数字、日期等
约束:有很多。其中一个叫唯一性约束。这种约束添加之后,该字段中的数据不能重复。
SQL语句分类
select 带有select关键字都是查询语句
对表里的数据进行操作:
insert 增
delete 删
update 改
带有create、drop、alter
对表的结构进行操作
create 新建等同于 增
drop 删除
alter 修改
这个增删改与DML不同,这个主要对表的结构操作
事务提交:commit
事务回滚:rollback
授权 grant、撤销权限revoke
mysql> source D:\Code\Mysql\databases.sql # 路径不要有中文
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)
select 字段名 from 表名;
# 注意:select和from都是关键字
# 字段名和表名都是标识符
mysql> select dname from dept;
+------------+
| dname |
+------------+
| ACCOUNTING |
| RESEARCH |
| SALES |
| OPERATIONS |
+------------+
4 rows in set (0.00 sec)
使用逗号隔开
# 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)
# 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)
# 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)
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 |
+--------+---------------+
select 字段1,字段2,...
from 表名
where 条件;
运算符 | 说明 |
---|---|
= | 等于 |
<>或 != | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
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)
# 默认是升序
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)
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)
查询员工名字和薪资,要求按照薪资升序,如果薪资一样的话,再按照名字升序排列
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)
关键字顺序不能改变,最后一步是排序
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)
数据处理函数又被称为单行处理函数
单行处理函数的特点:一个输入对应一个输出
和单行处理函数相对的是:多行处理函数(多行处理函数的特点:多个输入对应一个输出)
函数名称 | 解释 |
---|---|
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)
多行处理函数的特点:输入多行,输出一行
5个函数:
注意:分组函数在使用的时候必须先进行分组,然后才能使用。如果你每页对数据进行分组,整张表默认为一组
# 最高工资
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)
select
...
from
...
group by
...
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)
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 后面只能跟:参加分组的字段,以及分虚函数。其他的一律不能跟。
实现思路:按照部门编号,求出每一组的最大值
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)
每个部门最高薪资且最高薪资大于3000
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)
要求显示最高薪资大于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
找出每个部门平均薪资,要求显示平均薪资高于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)
select
...
from
...
group by
...
having
...
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)
查询结果去重,注意:原表数据不会被修改,只是查询结果去重,去重关键字: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)
跨表查询,多张表联合起来查询数据,被称为连接查询
根据语法查询的分类:
根据表连接的方式分类:
当两张表进行连接查询时,没有任何条件限制的时候,最终查询结果条数,时两张表条数的乘积,这种现象被称为:笛卡尔积现象
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)
注意:通过笛卡尔积现象得出,表的连接次数越多效率越低,尽量避免表的连接次数
查询每个员工所在部门名称
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
找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?
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)
查询员工的上级领导,要求显示员工名和对应的领导名
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)
以上就是内连接中的:自连接,技巧:一张表看作两张表
# 员工表
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)
select
...
from
a
join
b
on
a和b的连接条件
join
c
on
a和c的连接条件
join
d
on
a和d的连接条件
一条SQL中内连接和外连接可以混合出现
找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级?
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)
select语句中嵌套select语句,被嵌套的select语句称为子查询
select
...(select)
from
...(select)
where
...(select)
案例:找出比最低工资高的员工姓名和工资
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)
注意: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)
案例:找出每个员工的部门名称,显示部门名和员工名
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后面的子查询来说,这个子查询只能一次返回一条结果,多于一条,就报错
案例:查询工作岗位时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注意事项:
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)
每页显示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
select
...
from
...
group by -- 分组
...
having -- 过滤
...
order by -- 排序
...
limit -- 分页
...
# 执行顺序
1、from
2、where
3、group by
4、having
5、select
6、order by
7、limit
创建表语法格式:(创建表属于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_ 开始,可读性强。建名知意
字段名:建名知意
表名和字段名都属于标识符
数据类型 | 中文解释 |
---|---|
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流才可以 |
语法格式: 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
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)
数字格式化: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)
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)
注意:数据库中命名规范:所有的标识符都是小写,单词之间使用下划线链接
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)
**语法格式: **
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)
语法格式:
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
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)
原理:将一个查询结果当作一张表新建,可以快速完成表的复制,同时表中数据也保存了
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)
// 删除dept_bak表中的数据
delete from dept_bak; // 这种删除数据的方式比较慢
delete语句删除数据的原理?【DML】
表中的数据被删除了,但是这个数据再硬盘上的真是存储空间不会被释放。**缺点:**删除效率比较低 **优点:**支持回滚,可以恢复数据
truncate语句删除数据的原理:效率高,表被一次截断,物理删除。缺点:不支持回滚 优点:快速 【DDL】
truncate table dept_bak;
表数据非常大:删除时,使用delete需要1小时左右才能删除完,效率低 ==可以使用truncate:==删除表中数据。效率高。但是使用truncate之前,必须仔细询问客户是否真的要删除,并警告删除之后不可恢复
删除表操作
drop table 表名; // 这不是删除表中的数据,删除整个表
在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中的数据完整性和有效性
约束的作用:为了保证表中的数据有效
非空约束 | not null |
---|---|
唯一性约束 | unique |
主键约束 | primary key【简称PK】 |
外键约束 | foreign key【简称FK】 |
检查约束 | check(mysql不支持,Oracle支持) |
非空约束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
唯一性约束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)
需求:name和email两个字段联合起来具有唯一性
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255),
email vaarchar(255),
unique(name,email) // -- 约束没有添加再列的后面,这种约束称为表级约束
);
什么时候使用表级约束?
需要给多个字段联合起来添加某一个约束的时候,需要使用表级约束
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null unique
);
在mysql当中,如果一个字段同时被not null和unique约束的话,该字段自动变成字段【Oracle不一样】
主键:主键值时每一行记录的唯一标识
主键值时每一行记录的身份证号
主键的特征:not null + unique(主键值不能是NULL,同时也不能重复)
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)
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]');
在实际开发中不建议使用:复合主键。建议使用单一主键
**因为主键值存在的意义就是这行记录的身份证号,只要意义达到即可,单一主键可以做到。复合主键比较复杂,不建议使用 **
int、bingint、char等类型。
不建议使用:varchar来做主键。主键值一般都是数字,都是定长的
主键除了:单一主键和复合主键之外,还可以这样进行分类?
自然主键:主键值是一个自然数,和业务没关系
业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。
在实际开发中使用业务主键多,还是使用自然主键多一些?
自然主键使用比较多,因为主键只要做到不重复就行,不需要有意义
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');
外键约束涉及到相关术语:
外键约束:一种约束(foreign key)
外键字段:该字段上添加了外键约束
外键值:外键字段当中的每一个 值
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)
存储引擎是MySQL中特有的一个术语,其他数据库中没有(Oracle中有,但名字不一样)
实际上存储引擎是一个表存储/组织数据的方式
不同的存储引擎,表存储数据的方式不同
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)
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)
MyISAM存储引擎
一个事务就是一个完整的业务逻辑
**一个完整的业务逻辑:**假设转账,从A账户向B账户转账10000,将A账户的钱减去10000【update语句】,将B账户的钱加上10000【update语句】,这就是业务逻辑。
insert、delete、update只有这三个语句和事务有关,其他语句都没有关系【对数据库表中的数据进行增、删、改】
一个事务就是多条DML语句同时成功,或者同时失败
理解
创建索引
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)