MySQL(05)——SQL语句之多表查询

时间:2024-04-01 17:02:46

一个项目中肯定会有多张数据表,而数据表之间会存在各种各样的关系。这时我们需要的数据,可能不会直接通过一张表全部获取到,这时就需要同时查询多张数据表,得到最后想要的数据。
创建表以及准备数据:

create table A(
  A_ID int primary key auto_increment,
  A_NAME varchar(20) not null
);
insert into A values(1,'苹果');
insert into A values(2,'橘子');
insert into A values(3,'香蕉');

create table B( 
   A_ID int primary key auto_increment,
   B_PRICE double
);
insert into B values(1,2.30);
insert into B values(2,3.50);
insert into B values(4,null);

笛卡尔积介绍

笛卡尔积问题:把多张表放在一起,同时去查询,会得到一个结果,而这结果并不是我们想要的数据,这个结果称为笛卡尔积。
笛卡尔积的数据,对程序是没有意义的, 我们需要对笛卡尔积中的数据再次进行过滤。
对于多表查询操作,需要过滤出满足条件的数据,需要把多个表进行连接,连接之后需要加上过滤的条件。
MySQL(05)——SQL语句之多表查询

内连接

内连接查询的结果:两表的公共部分。
MySQL(05)——SQL语句之多表查询
内连接:
语法一:
select 列名 , 列名 … from 表名1,表名2 where 表名1.列名 = 表名2.列名;

select a.*,b.B_PRICE from a,b where a.A_ID=b.A_ID;

MySQL(05)——SQL语句之多表查询
语法二:
select 列名 , 列名 … from 表名1 inner join 表名2 on 条件

select a.*,b.B_PRICE from a inner join b on a.A_ID=b.A_ID;

MySQL(05)——SQL语句之多表查询

外连接

左外链接

MySQL(05)——SQL语句之多表查询

左外连接:用左边表去右边表中查询对应记录,不管是否找到,都将显示左边表中全部记录。
即:虽然右表没有香蕉对应的价格,也要把他查询出来。
语法:select * from 表1 left outer join 表2 on 条件;

select * from a left outer join b on a.A_ID=b.A_ID;

MySQL(05)——SQL语句之多表查询

右外连接

MySQL(05)——SQL语句之多表查询

用右边表去左边表查询对应记录,不管是否找到,右边表全部记录都将显示。
即:不管左方能够找到右方价格对应的水果,都要把左方的价格显示出来。
语法:select * from 表1 right outer join 表2 on 条件;

select * from a right outer join b on a.A_ID=b.A_ID;

MySQL(05)——SQL语句之多表查询

全连接

全外连接:左外连接和右外连接的结果合并,会去掉重复的记录。
select * from 表1 full outer join 表2 on 条件
select * from a full outer join b on a.A_ID = b.A_ID; 但是mysql数据库不支持此语法。
MySQL(05)——SQL语句之多表查询

在sql语句全连接,其实就是左外链接和右外连接之和,去掉重复的数据。可以使用union
语法:select * from 表1 left outer join 表2 on 条件 union select * from 表1 right outer join 表2 on 条件;

select * from a left outer join b on a.A_ID=b.A_ID
union
select * from a right outer join b on a.A_ID=b.A_ID;

MySQL(05)——SQL语句之多表查询

以上的outer均可以省略不写。

select * from a left join b on a.A_ID=b.A_ID;

MySQL(05)——SQL语句之多表查询

SQL关联子查询

子查询:把一个sql的查询结果作为另外一个查询的参数存在。
– 需求1:查询价格最贵的水果名称

select A_NAME from a
where A_ID in
	(select A_ID from b
		where b.B_PRICE=(select max(b.B_PRICE) from b));

或者写成(将每个字段在哪个表中注明):

select a.A_NAME from a
where a.A_ID in
	(select b.A_ID from b
		where b.B_PRICE=(select max(b.B_PRICE) from b));

MySQL(05)——SQL语句之多表查询

in和exists的用法

关联子查询其他的关键字使用:
age=23 or age=24 等价于 age in (23,24)
in 表示条件应该是在多个列值中。
in:使用在where后面,经常表示是一个列表中的数据,只要被查询的数据在这个列表中存在即可。

select * from a 
where a.A_ID in 
(select b.A_ID from b where b.B_PRICE>3)

exists:
exists:表示存在,当子查询的结果存在,就会显示主查询中的 当前行的所有数据。
语法: select * from 表名 where exists (子查询语句);

select * from a 
where exists
(select b.A_ID from b where b.B_PRICE>3 and a.A_ID=b.A_ID)

MySQL(05)——SQL语句之多表查询

all、any和some的使用

all 需要和 union 一起使用,如果在查询时, 单独使用union 可以把多个查询的结果进行合并, 会过滤掉重复的数据。如果union all 只会简单的把多个查询结果合并。

any 和 some用法一致:

SOME 是 SQL-92标准的ANY的等效物
any和some是没有区别的,some和any 效果一样 ,代表一部分记录。
MySQL(05)——SQL语句之多表查询

<any(1,2,3)  等价于 <1 or <2 or <3  等价与 <3   等价于 <max(1,2,3)  
>all(1,2,3)   等价与 >1 and >2 and >3   等价与>3   等价与 >max(1,2,3)
< all(1,2,3)  等价于 <1 and <2 and <3 等价于 <1   等价与 <min(1,2,3)

mysql的自带函数

如日期类的:
select current_date();
select now();

字符串:
select ucase(“abc”);
MySQL(05)——SQL语句之多表查询
数学函数:
select BIN(22);
select ABS(-20);