MySQL 中的约束

约束类型 :

• 非空约束(not null)

• 唯一性约束(unique)

• 主键约束(primary key) PK

• 外键约束(foreign key) FK

检查约束(目前 MySQL 不支持、Oracle 支持)

----创建表时添加约束

查询表中的约束信息

show keys from 表名

示例1:

创建 departments 表包含 department_id 该列为主键且自动增长,department_name 列不允许重复,location_id 列不允含有空值。




mysql根据参数长度查询 mysql查询结果作为参数_mysql 外键


查看表结构:


mysql根据参数长度查询 mysql查询结果作为参数_mysql根据参数长度查询_02


示例2:

创建 employees 表包含 employees_id 该列为主键且自动增长,last_name 列不允许含有空值,email 列不允许有重复不允许含有空值,dept_id 为外键参照 departments 表的主键。


mysql根据参数长度查询 mysql查询结果作为参数_mysql 外键_03


查看表结构:


mysql根据参数长度查询 mysql查询结果作为参数_mssql 将查询结果作为表名参数_04


----修改表实现约束的添加与删除

--主键约束

ALTER TABLE 表名 ADD PRIMARY KEY(列名)

示例:

将 emp 表中的 employee_id 修改为主键且自动增长

查看表结构:


mysql根据参数长度查询 mysql查询结果作为参数_mysql根据参数长度查询_05


添加主键:alter table emp add primary key(employee_id);


mysql根据参数长度查询 mysql查询结果作为参数_mysql根据参数长度查询_06


添加自动增长:alter table emp modify employee_id int auto_increment;


mysql根据参数长度查询 mysql查询结果作为参数_mysql 外键_07


--删除主键约束

alter table 表名 drop primary key;

注意:删除主键时,如果主键列具备自动增长能力,需要先去掉自动增长,然后在删除主键。

示例:

删除 employee_id 的主键约束

employee_id列的状态:


mysql根据参数长度查询 mysql查询结果作为参数_mysql id自动增长_08


去掉自动增长: alter table emp modify employee_id int;


mysql根据参数长度查询 mysql查询结果作为参数_mysql id自动增长_09


查看表结构:


mysql根据参数长度查询 mysql查询结果作为参数_mysql根据参数长度查询_10


删除主键:alter table emp drop primary key;


mysql根据参数长度查询 mysql查询结果作为参数_mysql id自动增长_11


查看表结构:


mysql根据参数长度查询 mysql查询结果作为参数_mysql根据参数长度查询_05


----非空约束

--添加非空约束

alter table 表名 modify 列名 类型 not null;

示例:

向 emp 表中的 salary 添加非空约束


mysql根据参数长度查询 mysql查询结果作为参数_mysql id自动增长_13


--删除非空约束

ALTER TABLE 表名 MODIFY 列名 类型 NULL

示例:

删除 salary 的非空约束


mysql根据参数长度查询 mysql查询结果作为参数_mssql 将查询结果作为表名参数_14


----唯一约束

--添加唯一约束

ALTER TABLE 表名 ADD CONSTRAINT 约束名 UNIQUE(列名)

示例:

向 emp 表中的 name 添加唯一约束


mysql根据参数长度查询 mysql查询结果作为参数_mysql id自动增长_15


--删除唯一约束

alter table 表名 drop key 约束名

示例:

删除 name 的唯一约束


mysql根据参数长度查询 mysql查询结果作为参数_mysql 外键_16


----外键约束

--添加外键约束

ALTER TABLE 表 名 ADD CONSTRAINT 约 束 名 FOREIGN KEY( 列 名 ) REFERENCES 参照的表名(参照的列名)

示例:

修改 emp 表,添加 dept_id 列


mysql根据参数长度查询 mysql查询结果作为参数_mysql根据参数长度查询_17


向 emp 表中的 dept_id 列添加外键约束。


alter table emp add constraint fk_dept_id foreign key(dept_id) references departments(department_id);


--删除外键约束

删除外键: ALTER TABLE 表名 DROP FOREIGN KEY 约束名

删除外键索引(索引名与约束名相同): ALTER TABLE 表名 DROP INDEX 索引名

示例:

删除 dept_id 的外键约束

删除外键:alter table emp drop foreign key fk_dept_id;

删除索引: alter table emp drop index fk_dept_id;

MySQL 中的 DML 操作

添加数据(INSERT)

--选择插入

insert into 表名(列名 1,列名 2,列名 3.....) VALUES(值 1,值 2,值 3......)

--完全插入

insert into 表名 VALUES(值 1,值 2,值 3......)

注意:如果主键是自动增长,需要使用 default 或者 null 或者 0 占位

自动增长(auto_increment)

MySQL 中的自动增长类型要求:

一个表中只能有一个列为自动增长。

自动增长的列的类型必须是整数类型。

自动增长只能添加到具备主键约束与唯一性约束的列上。

删除主键约束或唯一性约束,如果该列拥有自动增长能力,则需要先去掉自动增长然后在删除约束。

默认值处理

在 MySQL 中可以使用 DEFAULT 为字段设定一个默认值。如果在插入数据时并未指定该列的值,那么 MySQL 会将默认值添加到该列中。

--创建表时指定列的默认值

示例:

创建 emp3 表,该表包含 emp_id 主键且自动增长,包含 name,包含 address 该列默认值为”未知”。


create


--修改表添加列的默认值

示例:

修改 emp3 表,添加 job_id 该列默认值为 0


alter table emp3 add column job_id int default 0;


--插入数据时的默认值处理

示例:

如果在插入数据时并未指定该列的值,那么 MySQL 会将默认值添加到该列中。如果是完全项插入需要使用 default 来占位。

示例:

向 emp3 表中添加数据,要求 address 列与 job_id 列使用默认值作为该列的值


insert into emp3(name) values("admin"); 
insert into emp3 values(default,"oldlu",default,default);


更新数据(UPDATE)

update 表名 set 列名=值,列名=值 where 条件

注意:如果没有where条件,则更新整列

mysql 的 update 的特点:

• 更新的表不能在 set 和 where 中用于子查询;

• update 后面可以做任意的查询

示例1:

更新 emp3 表中的 id 为 1 的数据,添加 address 为 BeiJing


update emp3 e set e.address = "BeiJing" where emp_id = 1;


示例2:

更新 emp3 中 id 为 2 的数据,将地址修改为与 id 为 1 用户的地址相同

方式1:


update emp3 e ,(select address from emp3 where emp_id = 1)t 
                set e.address = t.address where e.emp_id =2;


方式2:


update emp3 e set e.address = 
      (select t1.address from (select emp_id, add ress from emp3)t1 where t1.emp_id = 1 ) 
       where e.emp_id = 2;


删除数据(DELETE)

--使用 DELETE 子句

delete from 表名 where 条件

示例:

删除 emp3 表中 emp_id 为 1 的雇员信息


delete from emp3 where emp_id = 1


--使用 TRUNCATE 清空表

truncate table 表名

示例:

删除 emp3 表中的所有数据


truncate table emp3;


--DELETE 与 TRUNCATE 区别

truncate 是整体删除(速度较快), delete 是逐条删除(速度较慢)

• truncate 不写服务器 log,delete 写服务器 log,也就是 truncate 效率比 delete 高的原因;

truncate 是会重置自增值,相当于自增列会被置为初始值,又重新从 1 开始记录,而不是接着原来的值。而 delete 删除以后,自增值仍然会继续累加

MySQL 中的事务处理

在 MySQL 中,默认情况下,事务是自动提交的,也就是说,只要执行一条 DML 语句就开启了事物,并且提交了事务

--关闭 MySQL 的事务自动提交

START TRANSACTION

DML(语句)

COMMIT|ROLLBACK

示例:

向 emp3 表中添加一条数据,要求手动提交事务


start transaction;
Query OK, 0 rows affected (0.00 sec) 

insert into emp3 values(default,"oldlu",default,default); 
Query OK, 1 row affected (0.00 sec) 

commit; 
Query OK, 0 rows affected (0.01 sec)


MySQL 查询数据

----MySQL 的基本查询

1) MySQL 的列选择

SELECT * | 投影列 FROM 表名

示例:

查询 departments 表中的所有数据


select * from departments;


2) MySQL 的行选择

SELECT * | 投影列 FROM 表名 WHERE 选择条件

示例:

查询 departments 表中部门 ID 为 4 的部门名称与工作地点 ID


select department_name,location_id from departments where department_id =4;


3) SELECT 语句中的算术表达式

+ :加法运算

- :减法运算

* :乘法运算

/ :除法运算,返回商

% :求余运算,返回余数

4) MySQL 中定义空值

包含空值的算术表达式计算结果为空。

示例 :

在 employees 中添加 commission_pct,计算年薪包含佣金。


alter table employees add column commission_pct float(5,2); 
select 12*salary*commission_pct from employees;


5) MySQL 中的列别名

SELECT 列名 AS 列别名 FROM 表名 WHERE 条件

示例:

查询 employees 表将雇员 laser_name 列名改为 name


select last_name as name from employees;


6) MySQL 中的连字符

MySQL 中并不支持||作为连字符,需要使用 concat 函数。在参数数量上与 oracle 的 concat函数有区别。 (支持多个字符串连接)

示例:

查询雇员表中的所有数据,将所有数据连接到一起,每列值中通过#分割


select concat(employees_id,'#',last_name,'#',email,"#",salary,"#",commission_pct) from employees;


7) MySQL 中去除重复

在 SELECT 语句中用 DISTINCT 关键字除去相同的行。

示例:

查询 employees 表,显示唯一的部门 ID。


select distinct dept_id from employees;


----约束和排序数据

---MySQL 中的比较条件

1) 比较运算符

• 等于=

• 大于>

• 大于等于>=

• 小于<

• 小于等于<=

• 不等于!=或<>

示例:

查询 employees 表,员工薪水大于等于 3000 的员工的姓名与薪水。


select * from employees where salary >=3000;


2) 模糊查询

• like

• %表示任意多个任意字符

• _表示一个任意字符

示例

查询 employees 中雇员名字第二个字母是 e 的雇员信息。

select * from employees where last_name like '_e%'

3) 逻辑运算符

• and

• or

• not

示例1:

查询 employees 表中雇员薪水是 5000 的并且名字中含有 d 的雇员信息


select * from employees where salary = 5000 and last_name like '%e%'


示例2:

查询 employees 表中雇员名字中不包含 u 的雇员信息


select * from employees where last_name not like '%u%'


4) 范围查询

• between ... and

• in 表示在一个非连续的范围内

示例1:

查询 employees 表,薪水在 3000-8000 之间的雇员信息


select * from employees where salary between 3000 and 8000


示例2:

查询 employyees 表,找出薪水是 5000,6000,8000 的雇员信息


select * from employees where salary in(5000,6000,8000)


5) 空值判断

• 判断空 is null

• 判断非空 is not null

示例1:

找出 emloyees 表中那些没有佣金的雇员


select * from employees where commission_pct is null;


示例2:

找出 employees 表中那些有佣金的雇员


select * from employees where commission_pct is not null;


---使用 ORDER BY 排序

• 用 ORDER BY 子句排序

• ASC: 升序排序,默认

• DESC: 降序排序

示例1:

查询 employees 表中的所有雇员,薪水按升序排序。


select * from employees order by salary


示例2:

查询 employees 表中的所有雇员,雇员名字按降序排序。


select * from employees order by last_name desc


MySQL 中常见的单行函数

1. 大小写控制函数

LOWER(str) 转换大小写混合的字符串为小写字符串

UPPER(str) 转换大小写混合的字符串为大写字符串。

2. 字符处理

CONCAT(str1,str2,...) 将 str1、str2 等字符串连接起来

SUBSTR(str,pos,len) 从 str 的第 pos 位(范围:1~str.length)开始,截取长度为 len的字符串

LENGTH(str) 获取 str 的长度

INSTR(str,substr) 获取 substr 在 str 中的位置

LPAD(str,len,padstr)/RPAD(str,len,padstr)

TRIM(str) 从 str 中删除开头和结尾的空格(不会处理字符串中间含有的空格)

LTRIM(str) 从 str 中删除左侧开头的空格

RTRIM(str) 从 str 中删除右侧结尾的空格

REPLACE(str,from_str,to_str) 将 str 中的 from_str 替换为 to_str(会替换掉所有符合

from_str 的字符串)

3. 数字函数

ROUND(arg1,arg2):四舍五入指定小数的值。

ROUND(arg1):四舍五入保留整数。

TRUNC(arg1,arg2):截断指定小数的值,不做四舍五入处理。

MOD(arg1,arg2):取余。

4. 日期函数

SYSDATE() 或者 NOW() 返回当前系统时间,格式为 YYYY-MM-DD hh-mm-ss

CURDATE() 返回系统当前日期,不返回时间

CURTIME() 返回当前系统中的时间,不返回日期

DAYOFMONTH(date) 计算日期 d 是本月的第几天

DAYOFWEEK(date) 日期 d 今天是星期几,1 星期日,2 星期一,以此类推

DAYOFYEAR(date) 返回指定年份的天数

DAYNAME(date) 返回 date 日期是星期几

LAST_DAY(date) 返回 date 日期当月的最后一天

5. 转换函数

DATE_FORMAT(date,format) 将日期转换成字符串(类似 oracle 中的 to_char())

STR_TO_DATE(str,format) 将字符串转换成日期(类似 oracle 中的 to_date())


mysql根据参数长度查询 mysql查询结果作为参数_mssql 将查询结果作为表名参数_18


mysql根据参数长度查询 mysql查询结果作为参数_mssql 将查询结果作为表名参数_19


示例1:

向 employees 表中添加 hire_date 列 类型为 date 类型


alter table employees add column hire_date date


示例2:

向 employees 表中添加一条数据,名字:King ,email:king@sxt.cn,部门 ID:1,薪水:9000,入职时间:2018 年 5 月 1 日,佣金:0.6


insert into employees values(default,'King','king@sxt.cn',1,9000,0.6,
          STR_TO_DATE('2018 年 5 月 1 日','%Y 年%m 月%d 日'))


示例3:

查询 employees 表中雇员名字为 King 的雇员的入职日期,要求显示格式为 yyyy 年 MM 月 dd 日。


select DATE_FORMAT(hire_date,'%Y 年%m 月%d 日') from employees where last_name = 'King'


6. 通用函数

IFNULL(expr1,expr2) 判断 expr1 是否为 null,如果为 null,则用 expr2 来代替 null (类似 oracle 的 NVL()函数)

NULLIF(expr1,expr2) 判断 expr1 和 expr2 是否相等,如果相等则返回 null,如果不相等则返回 expr1

IF(expr1,expr2,expr3) 判断 expr1 是否为真(是否不为 null),如果为真,则使用 expr2替代 expr1;如果为假,则使用 expr3 替代 expr1(类似 oracle 的 NVL2()函数)

COALESCE(value,...) 判断 value 的值是否为 null,如果不为 null,则返回 value;如果为 null,则判断下一个 value 是否为 null……直至出现不为 null 的 value 并返回或者返回最后一个为 null 的 value

CASE WHEN THEN ELSE END 条件函数

多表连接查询

----等值连接

示例:

查询雇员 King 所在的部门名称


select d.department_name from employees e,departments d 
     where e.dept_id = d.department_id and e.last_name = 'King'


----非等值连接

示例1:

创建 sal_level 表,包含 lowest_sal,highest_sal,level。


create table sal_level(lowest_sal int,highest_sal int ,level varchar(30));


示例2:

插入数据

1000 2999 A

2000 4999 B

5000 7999 C

8000 12000 D


insert into sal_level values(8000,12000,'D);


示例3:

查询所有雇员的薪水级别。


select e.last_name,s.level from employees e ,sal_level s where e.salary between s.lowest_sal and highest_sal;


----自连接

示例1:

修改 employees 表,添加 manager_id 列


alter table employees add COLUMN manager_id int


示例2:

修改数据 Oldlu 是 kevin 与 King 的经理

Taylor 是 Fox 的经理

示例3:

查询每个雇员的经理的名字以及雇员的名字。


select emp.last_name,man.last_name from employees emp ,employees man 
         where emp.manager_id = man.employees_id


外连接(OUTER JOIN)

----左外连接(LEFT OUTER JOIN)

向 employees 表中添加一条数据,名字:Lee,email:lee@sxt.cn,入职时间为今天。他没有薪水,没有经理,没有佣金。


insert into employees(last_name,email,hire_date) values('Lee','lee@sxt.cn',SYSDATE())


示例:

查询所有雇员的名字以及他们的部门名称,包含那些没有部门的雇员。


select e.last_name,d.department_name from 
          employees e LEFT OUTER JOIN departments d on e.dept_id = d.department_id


----右外连接(RIGHT OUTER JOIN)

向 departments 表中添加一条数据,部门名称为 Testing,工作地点 ID 为 5。


insert into departments values(default,'Testing',5)


示例:

查询所有雇员的名字以及他们的部门名称,包含那些没有雇员的部门。


select e.last_name,d.department_name from employees e 
           right OUTER join departments d on e.dept_id = d.department_id;


----全外链接

注意:MySQL 中不支持 FULL OUTER JOIN 连接

使用 union 实现全完连接

--UNION

可以将两个查询结果集合并,返回的行都是唯一的,如同对整个结果集合使用了DISTINCT。

--UNION ALL

只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。

语法结构 :

SELECT 投 影 列 FROM 表 名 LEFT OUTER JOIN 表 名 ON 连 接 条 件

UNION SELECT 投影列 FROM 表名 RIGHT OUTER JOIN 表名 ON 连接条件

示例:

查询所有雇员的名字以及他们的部门名称,包含那些没有雇员的部门以及没有部门的雇员。


(select e.last_name,d.department_name from employees e 
    LEFT OUTER JOIN departmentsd on e.dept_id = d.department_id) 
UNION (select e1.last_name,d1.department_name from employees e1 
    RIGHT OUTER JOIN departments d1 on d1.department_id = e1.dept_id)


SQL99 标准中的查询 (MySQL5.7 支持 SQL99 标准)

----SQL99 中的交叉连接(CROSS JOIN)

示例:

使用交叉连接查询 employees 表与 departments 表


select * from employees cross join departments


----SQL99 中的自然连接(NATURAL JOIN)

示例1:

修改 employees 表中的 dept_id 列将该列的名称修改为 department_id


alter table employees change column dept_id department_id int


示例2:

使用自然连接查询所有有部门的雇员的名字以及部门名称。


select e.last_name,d.department_name from employees e natural join departments d


----SQL99 中的内连接(INNER JOIN)

示例:

查询雇员名字为 OldLu 的雇员 ID,薪水与部门名称。


select e.employees_id,e.salary,d.department_name from employees e inner JOIN 
       departments d on e.department_id = d.department_id where e.last_name = 'Oldlu';


聚合函数

1. AVG(arg)函数

对分组数据做平均值运算。

arg:参数类型只能是数字类型。

2. SUM(arg)函数

对分组数据求和。

arg:参数类型只能是数字类型。

3. MIN(arg)函数

求分组中最小数据。

arg:参数类型可以是字符、数字、日期。

4. MAX(arg)函数

求分组中最大数据。

arg:参数类型可以是字符、数字、日期。

5. COUNT 函数

返回一个表中的行数。

COUNT 函数有三种格式:

• COUNT(*)

• COUNT(expr)

• COUNT(DISTINCT expr)

数据组(GROUP BY)

----创建数据组

示例:

计算每个部门的平均薪水


select avg(e.salary) from employees e group by e.department_id


----约束分组结果(HAVING)

示例:

显示那些最高薪水大于 5000 的部门的部门号和最高薪水。


select


子查询

可以将子查询放在许多的 SQL 子句中,包括:

• WHERE 子句• HAVING 子句

• FROM 子句

----使用子查询的原则

• 子查询放在圆括号中。

• 将子查询放在比较条件的右边。

• 在单行子查询中用单行运算符,在多行子查询中用多行运算符。

示例:

示例

谁的薪水比 Oldlu 高


select em.last_name,em.salary from employees em where em.salary > (select e.salary from 
                                                            employees e where e.last_name = 'Oldlu')


----单行子查询


mysql根据参数长度查询 mysql查询结果作为参数_mysql根据参数长度查询_20


示例:

查询 Oldlu 的同事,但是不包含他自己。


select empl.last_name from employees empl where empl.department_id = (select 
               e.department_id from employees e where e.last_name = 'Oldlu') and empl.last_name <> 'Oldlu'


----多行子查询


mysql根据参数长度查询 mysql查询结果作为参数_mssql 将查询结果作为表名参数_21


示例:

查找各部门收入为部门最低的那些雇员。显示他们的名字,薪水以及部门 ID。


select em.last_name,em.salary,em.department_id from employees em where em.salary 
                             in(select min(e.salary) from employees e group by e.department_id)


MySQL 中的正则表达式

• MySQL 中允许使用正则表达式定义字符串的搜索条件,性能要高于 like。

• MySQL 中的正则表达式可以对整数类型或者字符类型检索。

• 使用 REGEXP 关键字表示正则匹配。

• 默认忽略大小写,如果要区分大小写,使用 binary关

----正则表达式的模式及其含义


mysql根据参数长度查询 mysql查询结果作为参数_mysql id自动增长_22


--“^”符号

^在正则表达式中表示开始

语法:

查询以 x 开头的数据(忽略大小写)

SELECT 列名 FROM 表名 WHERE 列名 REGEXP '^x';

示例 :

查询雇员表中名字是以 k 开头的雇员名字与薪水。


select last_name,salary from employees where last_name REGEXP binary '^K'


--“$”符号

语法 :

查询以 x 结尾的数据(忽略大小写)

SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x$';

示例:

查询雇员表中名字是以 n 结尾的雇员名字与薪水。


select last_name,salary from employees where last_name REGEXP binary 'n$'


--“.”符号

语法 :

英文的点,它匹配任何一个字符,包括回车、换行等。

SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x.';

示例:

查询雇员表中名字含有 o 的雇员的姓名与薪水


select last_name,salary from employees where last_name REGEXP 'o.'


--“*”符号

语法 :

“*”:星号匹配 0 个或多个字符,在它之前必须有内容。

6“+”符号

语法:

"+":加号匹配 1 个或多个字符,在它之前也必须有内容。

SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x+';-匹配大于 1 个的任意字符

10.7“?”符号

语法:

“?”:问号匹配 0 次或 1 次。

SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'x?';-匹配 0 个或 1 个字符

10.8“|”符号

语法 :

“|”:表示或者含义

SELECT 列名 FROM 表名 WHERE 列名 REGEXP 'abc|bcd';-匹配包含 abc 或 bcd

示例 :

查询雇员表中名字含有 ke 或者 lu 的雇员的名字与薪水。


select last_name,salary from employees where last_name REGEXP 'ke|lu'


--“[a-z]”

语法:

“[a-z]”:字符范围

“^[....]”:以什么字符开头的

“[^....]”:匹配不包含在[]的字符

SELECT 列名 FROM 表名 WHERE 列名 REGEXP '[a-z]';-匹配内容包含 a-z 范围的数

示例1:

查询雇员表中名字包含 x、y、z 字符的雇员的名字和薪水。


select last_name,salary from employees where last_name REGEXP '[x-z]'


示例2:

查询雇员名字是 t、f 开头的雇员名字与薪水。


select last_name,salary from employees where last_name REGEXP '^[t|f]'


示例3:

查询雇员的名字与薪水,不包含 oldlu。


select last_name,salary from employees where last_name REGEXP '[^oldlu]'


--“{n}”

语法:

“{n}”:固定次数。

select * from student where name REGEXP 's{2}';--匹配以 s 连续出现 2 次的所有数据

示例:

查询雇员名字含有连续两个 e 的雇员的姓名与薪水


select last_name,salary from employees where last_name REGEXP 'e{2}'


示例二2:

查询名字中含有两个 o 的雇员的名字与薪水。


select last_name,salary from employees where last_name REGEXP 'o.{2}'


--“{n,m}”

语法 :

“{n,m}”:范围次数。

select * from student where name REGEXP '^s{2,5}';--匹配以 s 开头且重复 2 到 5 次的所有数据

示例 :

查询雇员名字中包含 1 个或者两个 o 的雇员姓名与薪水。


select last_name,salary from employees where last_name REGEXP 'o.{1,2}'