SQL之高级联结查询

来源:互联网 发布:清华知乎 编辑:程序博客网 时间:2024/05/20 13:39

之前有篇文章介绍了简单的联结查询,现在介绍稍微复杂一点的 联结,如果你没有看过之前的文章,请点击下面的链接。
联结查询和子查询

本次示例使用的数据库关系图
本次示例使用的数据库关系图

SQL联结方式

内联结

之前一篇文章已经介绍过内联结了,主要是用于寻找两个表中的相等条件建立联结.

内联结又可以分为下面三个方面:

联结方式 定义 等值联结 不进行列名的去重,即此时会有重复的字段.,使用 = 作为联结的条件 不等值联结 不进行列名的去重,即此时会有重复的字段.,使用 = 作为联结的条件 自然联结 在等值,不等值联结的基础上去除重复的列.

等值联结

不进行列名的去重,即此时会有重复的字段.,使用 = 作为联结的条件

-- 此时会有重复的列select *from customers inner join orderson orders.cust_id = customers.cust_id;/*    cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email, order_num, order_date, cust_id    1000000001  Village Toys    200 Maple Lane  Detroit MI  44444   USA John Smith  sales@villagetoys.com   20005   2004-05-01 00:00:00 10000000011000000001  Village Toys    200 Maple Lane  Detroit MI  44444   USA John Smith  sales@villagetoys.com   20009   2004-02-08 00:00:00 10000000011000000003  Fun4All 1 Sunny Place   Muncie  IN  42222   USA Jim Jones   jjones@fun4all.com  20006   2004-01-12 00:00:00 1000000003*/

不等值联结

使用 > < != 作为判断联结的条件

select customers.cust_id,count(orders.order_num) as num_ordfrom customers  inner join orderson customers.cust_id != orders.cust_idgroup by customers.cust_id;/*    cust_id, num_ord    1000000001  3    1000000002  5    1000000003  4    1000000004  4    1000000005  4*/

自然联结

在等值,不等值联结的基础上去除重复的列.

-- 此时不会有重复的数据select customers.cust_id,count(orders.order_num) as num_ordfrom customers  inner join orderson customers.cust_id = orders.cust_idgroup by customers.cust_id;/*    cust_id, num_ord    1000000001  2    1000000003  1    1000000004  1    1000000005  1*/

外联结

许多联结将一个表中的行与另一个表 中的行相关联,但有时候需要包含没有关联的那些行,此时需要使用外联结,外联结使用outer join关键字。

外联结方式 定义 左外联结 在左边的表中选择所有行 右外联结 在右边的表中选择所有行 全外联结 包含两个表中所有不关联的行

左外联结

-- 检索所有顾客的订单select customers.cust_id,orders.order_numfrom customers left outer join orderson orders.cust_id = customers.cust_id;/*    1000000001  20005    1000000001  20009    1000000002  NULL    1000000003  20006    1000000004  20007    1000000005  20008*/

全外联结

select customers.cust_id,orders.order_numfrom customers full outer join orderson orders.cust_id = customers.cust_id;

MySql不支持FULL OUTER JOIN,下面给出替代方法
select * from A left join B on A.id = B.id (where 条件)
union
select * from A right join B on A.id = B.id (where条件);

SQLite数据库不支持right outer join,只需将左右表调整位置即可解决这个问题。

交叉联结

在inner join(内查询)中不使用限定条件即为内查询,返回两个表对应列的笛卡尔积

使用带聚集函数的联结

聚集函数可以和表联结在一起使用,进行汇总数据.

-- 检索所有顾客及每个顾客的下单数select customers.cust_id,count(orders.order_num) as num_ordfrom customers inner join orderson customers.cust_id = orders.cust_idgroup by customers.cust_id;/*    1000000001  2    1000000003  1    1000000004  1    1000000005  1*/
-- 使用左外联结,可以检索到下单个数为0的客户select customers.cust_id,count(orders.order_num) as num_ordfrom customers left outer join orderson customers.cust_id = orders.cust_idgroup by customers.cust_id;/*    1000000001  2    1000000002  0    1000000003  1    1000000004  1    1000000005  1*/
1 0