SQL SERVER数据库的三种常用连接解析:

这里先给出一个官方的解释:
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
inner join(等值连接) 只返回两个表中联结字段相等的行 USE [BI]
GO
DROP TABLE BI.dbo.TABLE_ONE;
GO
DROP TABLE BI.dbo.TABLE_TWO;
GO
CREATE TABLE BI.dbo.TABLE_ONE(
[ID] [int] NOT NULL,
[NAME] [nvarchar]() NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE BI.dbo.TABLE_TWO(
[ID] [int] NOT NULL,
[SCORE] [int] NOT NULL
) ON [PRIMARY]
GO , 如果我两个表分别插入的是如下的信息: INSERT INTO BI.DBO.TABLE_ONE VALUES(,'张三');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'李四');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'王五');
GO
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
GO 在这种情况下:其实左连接和右连接,内连接的结果都是一样的: --左连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE LEFT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; --右连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE RIGHT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; --内连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE INNER JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; 得到的结果都是如下: 结论:如果两个表的记录数是一样的,而且主键的值也是一样的话,这个时候用什么连接他们的结果都是一样的。 , 如果我两个表分别插入的是如下的信息: truncate table BI.DBO.TABLE_ONE;
truncate table BI.DBO.TABLE_TWO; INSERT INTO BI.DBO.TABLE_ONE VALUES(,'张三');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'李四');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'王五');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'刘六');
GO
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
GO --左连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE LEFT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; 返回的是左表的4条记录,其中左边ID= 的在右表中存在连接的,所有右表对应的SCORE的值返回的是NULL。 --右连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE RIGHT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; 张三
李四
王五
NULL NULL 返回的是右表,TABLE_TWO的4条记录相应的记录,其中TABLE_TWO有ID= 的的记录,但是TABLE_ONE里没有,则返回NULL。 --内连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE INNER JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; ID NAME SCORE
张三
李四
王五 返回的是左右两个表都有的ID:,, 所以返回的是3条共有的记录值 。 结论:如果两个表是按照主键进行连接的话,左连接的话返回的记录集肯定是等于左表返回的记录数;右连接的话记录集肯定是等于右表返回的记录数;内连接就返回两个表都存在的记录。 上面都是以主键为连接条件的,对于左或右连接来说,得到的连接结果集肯定是等于连接中主表(左或右表)的记录数的。对于内连接,则返回的是两个表中都有的交集的记录数。下面来介绍一下不是按照主键来连接的情况下,这个时候最坏的记录数就是笛卡尔积个记录数。 , 如果我两个表分别插入的是如下的信息: truncate table BI.DBO.TABLE_ONE;
truncate table BI.DBO.TABLE_TWO; INSERT INTO BI.DBO.TABLE_ONE VALUES(,'张三');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'李四');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'王五');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'刘六');
GO
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
GO --左连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE LEFT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; 张三
张三
张三
张三
李四 NULL
王五 NULL
刘六 NULL 得出的结果集记录数7是大于主表左边4条记录的。 --右连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE RIGHT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; 张三
张三
张三
张三 --内连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE INNER JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; 张三
张三
张三
张三 ,下面就是极端的情况下,产生的是笛卡尔积。即两个表的记录数相乘个记录数。 truncate table BI.DBO.TABLE_ONE;
truncate table BI.DBO.TABLE_TWO; INSERT INTO BI.DBO.TABLE_ONE VALUES(,'张三');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'李四');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'王五');
INSERT INTO BI.DBO.TABLE_ONE VALUES(,'刘六');
GO
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
INSERT INTO BI.DBO.TABLE_TWO VALUES(,);
GO --左连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE LEFT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; --右连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE RIGHT JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; --内连接
SELECT TABLE_ONE.ID,TABLE_ONE.NAME,TABLE_TWO.SCORE
FROM TABLE_ONE INNER JOIN TABLE_TWO
ON TABLE_ONE.ID=TABLE_TWO.ID; 张三
张三
张三
张三
李四
李四
李四
李四
王五
王五
王五
王五
刘六
刘六
刘六
刘六 在这种情况下得出的结果集都是14条记录。 结论: 无论左,右连接得到的结果集的记录数肯定是大于等于主表的记录数的,而内连接的结果集可以是小于,等于,大于连接的表的记录数的。 左,右还是内连接表的一个重要的用处:可以横行的扩展一个表,可以得到一个有更多属性的新的表。 UNION 可以纵向的增加一个表的记录行数。

全面解析SQL SERVER 的左右内连接的更多相关文章

  1. 深入解析SQL Server并行执行原理及实践(上)

    在成熟领先的企业级数据库系统中,并行查询可以说是一大利器,在某些场景下他可以显著的提升查询的相应时间,提升用户体验.如SQL Server, Oracle等, Mysql目前还未实现,而Postgre ...

  2. SQL Server DAC——专用管理员连接

    今天打开数据库刚要连接时,看到“连接到服务器”窗口,突发的想到:要是SQL Server 不再响应正常的连接请求,又想使用数据库时,我们该怎么办?      其实我们还能通过“SQL Server D ...

  3. SQL Server利用RowNumber()内置函数与Over关键字实现通用分页存储过程(支持单表或多表结查集分页)

    SQL Server利用RowNumber()内置函数与Over关键字实现通用分页存储过程,支持单表或多表结查集分页,存储过程如下: /******************/ --Author:梦在旅 ...

  4. JDBC与SQL SERVER各个版本的连接方法

    转至:blog.csdn.net/ying5420/article/details/4488246 1.SQL SERVER 2000 JDBC驱动程序:msbase.jar.mssqlserver. ...

  5. 解决SQL Server管理器无法连接远程数据库Error: 1326错误

    解决SQL Server管理器无法连接远程数据库Error: 1326错误 我们在在使用SQL Server时都会遇到使用SQL Server Management Studio无法连接远程数据库实例 ...

  6. SQL Server 2005无法远程连接的解决方法

    以前一直连接本地的数据库,连接SQL Server 2005是小菜的... 做项目也是老师搭好了服务器端,打上IP去访问就行...也不用考虑太多. 今天自己在公司搭SQL Server 2005服务器 ...

  7. JDBC连接SQL server与ADO.NET连接Sql Server对比

    JDBC连接SQL server与ADO.NET连接Sql Server对比 1.JDBC连接SQL server 1)java方面目前有很多驱动能够驱动连接SQL servernet.   主流的有 ...

  8. 利用Ring Buffer在SQL Server 2008中进行连接故障排除

    原文:利用Ring Buffer在SQL Server 2008中进行连接故障排除 出自:http://blogs.msdn.com/b/apgcdsd/archive/2011/11/21/ring ...

  9. sql server 2008 64位连接sql 2000服务器的时候出现

    来源 https://blog.csdn.net/loeley/article/details/7095741 sql server 2008 64位连接sql 2000服务器的时候出现以下提示: 链 ...

随机推荐

  1. 学java入门到精通,不得不看的15本书

    学java入门到精通,不得不看的15本书 一.Java编程入门类1.<Java编程思想>2.<Agile Java>中文版 二.Java编程进阶类1.<重构 改善既有代码 ...

  2. #maven解决乱码问题

    <build>        <plugins>        <plugin>        <groupId>org.apache.maven.pl ...

  3. C Struct Hack

    It's not clear if it's legal or portable, but it is rather popular. #include <stdlib.h> #inclu ...

  4. Java Hashtable类

    哈希表(Hashtable)是原来的java.util中的一部分,是一个字典的具体实现. 然而,Java2重新设计的哈希表,以便它也实现了​​Map接口.因此,哈希表现已集成到集合框架.它类似于Has ...

  5. Android进阶笔记19:onInterceptTouchEvent、onTouchEvent与onTouch

    1.onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后, ...

  6. centos下查看rpm包安装位置

    1.如何安装rpm软件包 rpm -ivh your-package.rpm其中your-package.rpm是你要安装的rpm包的文件名,一般置于当前目录下. 2.如何卸载rpm软件包使用命令 r ...

  7. uva 10252 - Common Permutation 字符串水题

    题意:給定兩個小寫的字串a與b,請印出皆出現在兩字串中的字母,出現的字母由a~z的順序印出,若同字母出現不只一次,請重複印出但不能超過任一字串中出現的次數.(from Ruby兔) 很水,直接比较输出 ...

  8. 重构20-Extract Subclass(提取父类)

    当一个类中的某些方法并不是面向所有的类时,可以使用该重构将其迁移到子类中.我这里举的例子十分简单,它包含一个Registration类,该类处理与学生注册课程相关的所有信息. public class ...

  9. 推荐一款好用的项目管理工具:project

    Microsoft Project (MSP)是微软开发的一个国际上享有盛誉的通用的项目管理工具软件. 在项目管理的时候,这个软件可以帮你定制时间计划,还有其它很多好用的功能. 2010版本的下载传送 ...

  10. 【Linux】Shell脚本编程(一)

    Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...