连接查询
1.基本概念:就是将两个或两个以上的表,连接起来,当做一个数据源,并从中取得所需要的数据。
连接方式:将每一个表的每一行数据两两之间相互对接起来,每次对接的结果都是连接结果的“一行”数据。
没有条件的连接,形式为:
Select* from 表1,表2;
Select* from 表1 join 表2;
Select* from 表1 cross join 表2;
2.连接基本形式:
表1 【连接形式】 join 表2 【on 连接条件】;
如果是3个表,则进一步扩展:
表1 【连接形式】 join 表2 【on 连接条件】 【连接形式】 join 表3 【on 连接条件】;
3.连接的分类
(1)交叉连接(cross join):没有连接条件,知识按连接的基本概念将所有数据行都连接起来的结果,又叫做“笛卡尔积”。
对于表1(n1个字段,n2行),表2(m1个字段,m2行),交叉连接的结果是:
有n1+m1个列,n2+m2个行;
形式有:
Select* from 表1,表2;
Select* from 表1 join 表2;
Select* from 表1 cross join 表2;
(2)内连接(inner join):找出交叉连接中有意义的数据
形式:
Select* from 表1 【inner】 join 表2 on 连接条件;
连接条件,简单的说是“外键关系”的一个描述(没有外键关系也可以使用)
例如:
select * from product inner join product_type on product.protype_id=product_type.protype_id;
简化:
select * from product as A inner join product_type as B onA.protype_id=B.protype_id;
select A.*,t.protype_name from product as A inner join product_type as B onA.protype_id=B.protype_id;
(2)左(外)连接left(outer) join:
形式:表1(左表) left 【outer】 join 表2(右表) on 连接条件;
含义:将两个表内连接的结果,再加上左边表的不符合内连接所设定的条件的那些数据的结果(右表中没有的值,为NULL)。
即,左边表的数据全部取出。
(3)右(外)连接right (outer) join
形式:表1(左表) right 【outer】 join 表2(右表) on 连接条件;
含义:将两个表内连接的结果,再加上右边表的不符合内连接所设定的条件的那些数据的结果。
即,右边表的数据全部取出,左表中没有对应数据则为NULL。
(4)全(外)连接 full(outer) join
形式:mysql不支持全连接的语法
含义:将两个表内连接的结果,再加上左边表的不符合内连接所设定的条件的那些数据的结果以及左边表的不符合内连接所设定的条件的那些数据的结果。
连接查询举例:
例1:查出每个品种各有多少个商品
select p.protype_id,product_name,count(*) as 数量
from product as p inner join product_type as t on p.protype_id=t.protype_id
group by p.protype_id;
例2:查出计算机系的所有学生信息
select s.* from stuinfo as s inner join yuanxi as y ons.yuanxi_id=y.yuanxi_id
where yuanxi_name=’计算机系’;
子查询
概念:
在一个查询语句(select语句)中的内部,某些位置(select部分,from部分,where部分),又出现的“查询语句”。
则有两个概念:主查询、子查询
通常子查询是为主查询服务的,通常都是子查询获得一定的结果数据后,才去执行主查询。
分类:
(1)按子查询结果分为:
表子查询:一个子查询的结果是以“多行多列”的时候,此时可以当作一个表来使用,通常放在from后面
行子查询:结果是一行多列的形式,可当作行来使用,通常放在“行比较语法”中。
行比较语法:where row(字段1,字段2)=(select 行子查询)
列子查询:返回结果是多行一列,可当作多个值来使用,类似于:(5,17,8,22)
标量子查询:结果是一行一列,可当作单个值来使用
(2)按位置分类:
作为主查询的结果数据:
Select c1,(select f1 from tab2) as fl1 from tab1;#这里子查询应该只有一个数据(标量子查询)
作为主查询的条件数据:
Select c1 fromtab1 where c1 in (select f1 from tab2);#这里子查询可以是多个数据(多行一列、列子查询)
作为主查询的来源数据:
Select c1 from(select f1 as c1,f2 from tab2) ast2; #这里子查询可以是任意查询结果(表子查询)
常见子查询
(1)比较运算符中的子查询:
形式:操作数 比较运算符 (标量子查询)
说明:操作数,其实就是比较运算符的2个数据之一而已,通常就是一个字段名
例:select * from productwhere price=(select max(price) from product);
(2)使用in的子查询
形式:操作数(字段名) in (列子查询)
举例:select * from productwhere protype_id in (select protype_id from product_type where protype_namelike ‘%电%’);
(3)使用any的子查询
形式:操作数 比较运算符 any(列子查询);
含义:当某个操作数(字段)对于该列子查询的其中的任意一个值,满足该比较运算符,则就算满足了条件。
例:select * from tab1 whereid > any (select f1 from tab2);
(4)使用all的子查询
形式:操作数 比较运算符 all(列子查询);
含义:当某个操作数(字段)对于该列子查询的其中的所有值,都满足该比较运算符,则满足了条件(要求全部都满足)。
例:select * from tab1 whereid < all (select f1 from tab2);
举例:
查询所有非最高价的商品;(至少会小于所有价格中的一个)
Select * from product where price < any(selectprice from product);
查询所有最高价的商品(大于等于所有价格)
Select * from product where price >= all(selectprice from product);
(5)使用some的子查询
some是any的同义词
(6)使用exists的子查询
形式:where exists(子查询)
含义:该子查询如果“有数据”,则exists的结果是true,否则就是false
例:
select * from product where exists
(select * from product_type
whereprotype_name like ‘%电%’ and protype_id=product.protype_id);
product为主查询表,后边的等式是隐含的连接条件
注意:
1.这种子查询不可独立运行,必须与主查询配合使用;
2.该子查询中的条件,应该设定为跟主查询的某个字段有一定的关联性判断,通常该判断就是这两个表的“本来该有的连接条件”(外键关系等)
2.其他子查询可以独立运行;
结论:如果一个查询需求,可以使用一个连接查询得到,也可以使用一个子查询得到,则推荐使用连接查询,效率更高。
联合查询union
基本概念:将两个具有相同字段数的查询语句的结果,以上下堆叠的方式合并为一个查询结果。
例:select id,f1,f2 from jointable1
Union
select id2,c1,f2 from jointable2;
结果以第一个select语句的字段为准,默认情况下,order by 与limit子句只能对整个联合后的结果进行排序和数量限定。如果第一个select语句中有别名,则使用order by 时必须使用该别名。
两个select语句的字段数一致,字段类型一致。
语法形式:
Select语句1
Union 【all |distinct】
Select语句2;
默认会“自动消除重复行”,即默认是distinct,如果想要显示所有行,就使用all
应用:用union实现全外连接:
Select * from 表1 left join 表2 on 条件
Union
Select * from 表1 right join 表2 on 条件;