MySQL高级查询

多表查询

当前的应用系统在存储数据的时候为了⽅便对数据进⾏管理,都不会将所有的数据存放在⼀个数据库表中,比如:员⼯的个⼈资料和部门信息是分开存放在不同的表中的,但是员⼯个⼈信息中会标记出其所在的部门。此时在进⾏员⼯信息查询时,会涉及到多个表;

连接查询:同时涉及多个表的查询
连接条件或连接谓词:用来连接两个表的条件

⼀般格式:

[表名1.]<列名1> <比较运算符> [表名2.]<列名2>	
[表名1.]<列名1> BETWEEN [表名2.]<列名2> AND [表名2.]<列名3>

• 连接条件中的各连接字段类型必须是可比的,但名字不必相同。

常⻅连接查询

  • 内连接
  • 外连接
  • 复合条件连接

内连接—等值连接

例:查询每个员⼯所在的部门
内连接的写法:
第⼀种:使用连接符 =

select * from emp,dept where Dept_id = dept.id;

第⼆种:使用 join .. on..

select * from emp join dept	on Dept_id = dept.id;

第三种:使用 inner join .. on..

select * from emp inner join dept on Dept_id = dept.id;

⾮等值连接查询

员⼯信息表enginfo

⼯资等级表salgrade

select e.ename as '姓名',s.id as '等级' from	enginfo e,salgrade s
where e.sal BETWEEN s.local	and s.maxline;

⾃身连接

  • 自身连接:⼀个表与其自⼰进⾏连接
  • 需要给表起别名以示区别
  • 由于所有属性名都是同名属性,因此必须使用别名前缀

例如:查询每门课程的先修课名称

SELECT Qir.cno,Qir.cname, Qir.cpno,sec.cname
FROM course	Qir, course sec	
WHERE Qir.cpno = sec.cno

外连接

  • 外联接可以是左向外联接、右向外联接
  • 在 FROM⼦句中指定外联接时,可以由下列⼏组关键字中的⼀组指定:
    LEFT JOIN或LEFT OUTER JOIN
    RIGHT JOIN 或 RIGHT OUTER JOIN

左连接

  • 左向外联接的结果集包括 LEFT OUTER⼦句中指定的左表的所有⾏,⽽不仅仅是联接列所匹配的⾏。
  • 如果左表的某⾏在右表中没有匹配⾏,则在相关联的结果集⾏中右表的所有选择列表列均为空值。

例:

SELECT s.sno, sname, sex, age, dept, cno, grade	
FROM student s LEFT OUT JOIN sc ON s.sno=sc.sno

右连接

右向外联接是左向外联接的反向联接。将返回右表的所有⾏。如果右表的某⾏在左表中没有匹配⾏,则将为左表返回空值。

外键

什么是外键:
是另⼀表的主键, 外键可以有重复的, 可以是空值,用来和其他表建立联系用的。

主外键关系

在上图上涉及的两个表中学⽣信息表 (stuInfo)为主表,学⽣成绩表(score)为从表;那么主从表之间有什么关系呢?
1、当主表中没有对应的记录时,不能将记录添加到⼦表
学⽣成绩表中不能出现学⽣信息表中没有的学号;
2、不能更改主表中的值⽽导致⼦表中的记录孤立
学⽣信息表中的id变化了,学⽣成绩表中的id也要随着
发⽣改变;
3、⼦表存在与主表对应的记录,不能从主表中删除该⾏
不能把部门表中的数据删除
4、删除主表前,先删⼦表
先删除成绩表、后删除学⽣信息表;

外键的使⽤

外键的使用需要满⾜下列的条件:
1、两张表必须都是InnoDB表,并且它们没有临时表。
2、建立外键关系的对应列必须具有相似的InnoDB内部数据类型。
3、建立外键关系的对应列必须建立了索引。

创建外键的两种⽅式:
⽅式⼀:在创建表的时候进⾏添加。
⽅式⼆:表已经创建好了,继续修改表的结构来添加外键。

在创建表的时候添加外键:

create table stuInfo(	
Scode int primary	key,-- 学⽣的学号 
Sname char(10),-- 学⽣的姓名 
Saddress varchar(50),-- 学⽣的住址 
Sgrade int,-- 学⽣所在班级 
Semail varchar(50),-- 学⽣的邮箱地址 
Sbrith date	
)DEFAULT CHARSET='utf8';	
create table score(	
studentID int,	
coureseID int,	
score int,	
scoreID int	primary	key,	
foreign key(studentID) references stuInfo(Scode) -- 添加外键 
)DEFAULT charset='utf8';

删除外键:

语法:alter table 表名称 drop foreign key 外键名称;	
例:alter table score drop foreign key score_ibQk_1;	
注意:如果没有在建表的时候标明外键名称,可以通过:
show create table 表名 进⾏查看外键名称;

建表以后添加外键:

语法:alter table 表名称 add foreign key (列名称) references		
关联表名称(列名称);	
例:alter table stuInfo add foreign key (scode) references	
score(studentID);

⼦查询

  • ⼦查询允许把⼀个查询嵌套在另⼀个查询当中。
  • ⼦查询可以包含普通select可以包括的任何⼦句,比如:distinct、 group by、order by、limit、join和union等;但是对应的外部查询必须是以下语句之⼀:select、insert、update、delete、set或者do。

⼦查询的分类

  1. 标量⼦查询:
    返回单⼀值的标量,最简单的形式。
    2.列⼦查询:
    返回的结果集是 N ⾏⼀列。
  2. ⾏⼦查询:
    返回的结果集是⼀⾏ N 列。
  3. 表⼦查询:
    返回的结果集是 N ⾏ N 列
    可以使用的操作符:= > < >= <= <> ANY IN
    SOME ALL EXISTS

标量⼦查询

是指⼦查询返回的是单⼀值的标量,如⼀个数字或⼀个字符串,也是⼦查询中最简单的返回形式。 可以使用 = > < >= <= <> 这些操作符对⼦查询的标量结果进⾏比较,通常⼦查询的位置在比较式的右侧

SELECT * FROM article WHERE uid = (SELECT uid FROM user
WHERE status=1 ORDER BY uid DESC LIMIT 1)		
SELECT * FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2) 	
SELECT * FROM article AS t WHERE 2 = (SELECT COUNT(*) FROM article WHERE article.uid =t.uid)

列⼦查询

指⼦查询返回的结果集是 N ⾏⼀列,该结果通常来自对表的某个字段查询返回。
可以使用 IN、ANY和 ALL 操作符

SELECT * FROM article WHERE uid IN(SELECT uid FROM user WHERE status=1)		
SELECT s1 FROM table1 WHERE s1 > ANY (SELECT s2 FROM table2)		
SELECT s1 FROM table1 WHERE s1 > ALL (SELECT s2 FROM table2)		

⾏⼦查询

指⼦查询返回的结果集是⼀⾏ N 列,该⼦查询的结果通常是对表的某⾏数据进⾏查询⽽返回的结果集。

SELECT * FROM article WHERE (title,content,uid) = 
(SELECT title, content,uid FROM blog WHERE bid=2)	

表⼦查询

指⼦查询返回的结果集是 N ⾏ N 列的⼀个表数据。

SELECT * FROM article WHERE (title,	content, uid)	
IN (SELECT title, content, uid FROM blog)		

EXIST谓词

EXISTS是⼀个非常⽜叉的谓词,它允许数据库⾼效地检查指定查询是否产⽣某些⾏。

select * from t1 where city=‘beijing' and exists		
(select * from t2 where t1.cid=t2.cid);	

派⽣表

在⼦查询返回的值中,也可能返回⼀个表,如果将⼦查询返回的虚拟表再次作为FROM⼦句的输⼊时,这就⼦查询的虚拟表就成为了⼀个派⽣表。

FROM (subquery expression) AS derived_table_alias

派⽣表使⽤

派⽣表⼀般与外连接,分组统计⼀起使用

SELECT t1.name,t2.sex,a.city,a.age FROM t1,
(SELECT city, MAX(age) FROM t2 GROUP BY city) a	
WHERE t1.age=t2.age;

联合查询

使用UNION或UNION ALL关键字

相同结果被筛选掉了

SELECT cname,sex FROM users	
UNION						
SELECT name,sex FROM teacher;

有ALL,保留相同项

SELECT cname,sex FROM users	
UNION ALL				
SELECT name,sex FROM teacher;
posted @ 2019-12-01 07:00  心脏鼓点  阅读(1080)  评论(0编辑  收藏  举报