你真的会玩SQL吗?内连接、外连接

简介: 原文:你真的会玩SQL吗?内连接、外连接大多数人一般写多表查询会这样写select * from tbA ,tbB  没有用到JOIN关键字,太Low了,官网标准建议是用JOIN明确表间的关系,下面具体来讲。
原文: 你真的会玩SQL吗?内连接、外连接

大多数人一般写多表查询会这样写select * from tbA ,tbB  没有用到JOIN关键字,太Low了,官网标准建议是用JOIN明确表间的关系,下面具体来讲。
 
连接类型:
  1. 交叉联接 得到所连接表的所有组合 (笛卡儿集)cross join
  2. 内联接得到连接表的满足条件的记录组合inner join  on
  3. 外联接(左、右)得到一个表的所有行,及其余表满 足连接条件的行 full | left | right  outer join  on

     交叉联接  

  在这类联接的结果集内,两个表中每两个可能成对的行占一行。

    但是如果在交叉联接中加入where 子句就相当与是内联接

    例:

SELECT title, pub_name

       FROM titles Cross JOIN publishers

       Where titles.pub_id = publishers.pub_id

这就相当于我们一最开始的写法:SELECT title, pub_name  FROM titles , publishers Where titles.pub_id = publishers.pub_id

执行过程:

 

       内联接  

仅显示两个联接表中的匹配行的联接。(这是查询设计器中的默认联接类型。)

例:

SELECT title, pub_name

       FROM titles INNER JOIN publishers

       ON titles.pub_id = publishers.pub_id

   执行过程:

 

     左向外联接  

包括第一个命名表("左"表,出现在 JOIN 子句的最左边)中的所有行。不包括右表中的不匹配行。

例:

SELECT titles.title_id,titles.title,publishers.pub_name

        FROM titles LEFT OUTER JOIN publishers

        ON titles.pub_id = publishers.pub_id

 

右向外联接  

包括第二个命名表("右"表,出现在 JOIN 子句的最右边)中的所有行。不包括左表中的不匹配行。

例:

SELECT titles.title_id, titles.title,publishers.pub_name

  FROM titles RIGHT OUTER JOIN publishers

        ON titles.pub_id = publishers.pub_id

 执行过程:

 

完整外部联接  

包括所有联接表中的所有行,不论它们是否匹配。

例:

SELECT titles.title_id, titles.title,  publishers.pub_name

        FROM titles FULL OUTER JOIN publishers

        ON titles.pub_id = publishers.pub_id

 

练习:

此后用到的用例数据库是SQL2008里面的

用例数据库文件:链接:http://pan.baidu.com/s/1qW1QxA0 密码:dqxx

/*返回值2007年2月12日下过订单的客户,以及他们的订单。同时也返回在2007年2月12日没有下过订单的客户。
涉及到表:Sales.Customers表和Sales.Orders表。
期望的输出(按简略格式显示):
*/
custid      companyname     orderid     orderdate
----------- --------------- ----------- -----------------------
72          Customer AHPOP  NULL        NULL
58          Customer AHXHT  NULL        NULL
25          Customer AZJED  NULL        NULL
18          Customer BSVAR  NULL        NULL
91          Customer CCFIZ  NULL        NULL
...
33          Customer FVXPQ  NULL        NULL
53          Customer GCJSG  NULL        NULL
39          Customer GLLAG  NULL        NULL
16          Customer GYBBY  NULL        NULL
4           Customer HFBZG  NULL        NULL
5           Customer HGVLZ  10444       2007-02-12 00:00:00.000
42          Customer IAIJK  NULL        NULL
34          Customer IBVRG  NULL        NULL
63          Customer IRRVL  NULL        NULL
73          Customer JMIKW  NULL        NULL
15          Customer JUWXK  NULL        NULL
...
21          Customer KIDPX  NULL        NULL
30          Customer KSLQF  NULL        NULL
55          Customer KZQZT  NULL        NULL
71          Customer LCOUJ  NULL        NULL
77          Customer LCYBZ  NULL        NULL
66          Customer LHANT  10443       2007-02-12 00:00:00.000
38          Customer LJUCA  NULL        NULL
59          Customer LOLJO  NULL        NULL
36          Customer LVJSO  NULL        NULL
64          Customer LWGMD  NULL        NULL
29          Customer MDLWA  NULL        NULL
...

参考SQL:

--answer:
select c.custid,c.companyname,o.orderid,o.orderdate
from Sales.Customers as c
left join Sales.Orders as o
on c.custid=o.custid 
and o.orderdate='2007-2-12'
/*
1.将表Sales.Customers别名为c和表Sales.Orders别名为o应用ON筛选器以custid和o.orderdate='2007-2-12'为条件左外连接,生成虚拟表VT1,
2.添加外部行,外部行中非保留表中的属性被赋值为NULL,生成虚拟表VT2
3.处理select列表,从虚拟表VT2中查找出c.custid,c.companyname,o.orderid,o.orderdate生成虚拟表VT3
*/

注意
and o.orderdate='2007-2-12' 改成 where  o.orderdate='2007-2-12',请注意这个结果又是什么呢?
View Code

 

/*返回没有下过订单的客户。
涉及的表:Sales.Customers表和Sales.Orders表。
期望的输出:
*/
custid      companyname
----------- ---------------
22          Customer DTDMN
57          Customer WVAXS

参考SQL:

--answer:
select c.custid,c.companyname
from Sales.Customers as c
left join Sales.Orders as o
on c.custid=o.custid 
where o.orderid is null
/*
1.将表Sales.Customers别名为c和表Sales.Orders别名为o应用ON筛选器以custid为条件左外连接,生成虚拟表VT1,
2.添加外部行,外部行中非保留表中的属性被赋值为NULL,生成虚拟表VT2
3.应用where筛选器选出o.orderid 为 null的数据生成虚拟表VT3
4.处理select列表,查找出c.custid,c.companyname生成虚拟表VT4
*/
View Code

 

目录
相关文章
|
8天前
|
SQL 安全 网络安全
IDEA DataGrip连接sqlserver 提示驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接的解决方法
IDEA DataGrip连接sqlserver 提示驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接的解决方法
19 0
|
1月前
|
SQL
SQL多表查询的几种连接方式
SQL多表查询时,主要使用以下几种连接方式
|
2月前
|
SQL 消息中间件 分布式数据库
flink sql问题之连接HBase报错如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
185 0
|
2月前
|
SQL 网络协议 Java
【Java+SQL Server】前后端连接小白教程
【Java+SQL Server】前后端连接小白教程
24 0
|
3月前
|
SQL
在SQL中连接和复杂操作
在SQL中连接和复杂操作
22 0
|
3月前
|
SQL 数据库
面试题:Sql中的连接
面试题:Sql中的连接
28 5
|
3月前
|
SQL 关系型数据库 数据库连接
Python 连接 SQL 数据库 -pyodbc
以下是如何在 Python 中使用 pyodbc 连接到 SQL 数据库的基本步骤和详解
52 0
|
4月前
|
SQL 数据库
SQL FULL OUTER JOIN 关键字:左右表中所有记录的全连接解析
SQL RIGHT JOIN关键字返回右表(table2)中的所有记录以及左表(table1)中的匹配记录。如果没有匹配,则左侧的结果为0条记录。
65 0
|
4月前
|
SQL Java 关系型数据库
在IDEA中配置MySQL数据库连接以及在使用mybatis时设置sql语句的代码提示功能
在IDEA中配置MySQL数据库连接以及在使用mybatis时设置sql语句的代码提示功能
|
4月前
|
SQL 安全 网络安全
解决:provider:Named Pipes Provider error:40无法打开SQL Server的连接 的3种方式
解决:provider:Named Pipes Provider error:40无法打开SQL Server的连接 的3种方式
210 0