设为首页 收藏本站
查看: 624|回复: 0

[经验分享] SQL Server-交叉联接、内部联接基础回顾(十二)

[复制链接]

尚未签到

发表于 2017-7-13 07:56:58 | 显示全部楼层 |阅读模式
前言
  本节开始我们进入联接学习,关于连接这一块涉及的内容比较多,我们一步一步循序渐进学习,简短内容,深入的理解,Always to review the basics。

交叉联接(CROSS JOIN)
  交叉连接是最简单的联接类型。交叉联接仅执行一个逻辑查询处理阶段-笛卡尔乘积。例如对两个输入表进行操作,联接并生成两个表的笛卡尔乘积,也就是说,将一个表的每一行与另一个表的所有行进行匹配。所以,如果一个表有m行,另一个表有n行,得到的结果中则会有m*n行。我们就拿SQL Server 2012教程中的例子说下



SELECT C.custid, E.empid
FROM Sales.Customers AS C
CROSS JOIN HR.Employees AS E
ORDER BY E.empid
  在Sales.Customers表中有91行数据,HR.Employees表中有9行数据,则利用交叉联接数据则有819(91*9)行数据,简略数据如下。
DSC0000.png

  交叉联接我们可以用如下图表示
DSC0001.jpg

  交叉联接最大的用途在于生成数字表以便我们用于其他目的,我们一起来看看。



IF OBJECT_ID('dbo.Digits','U')
IS NOT NULL DROP TABLE dbo.Digits;
CREATE TABLE dbo.Digits
(
digit INT NOT NULL
);
  插入10条基础数据



USE TSQL2012
GO
INSERT INTO dbo.Digits
( digit )
VALUES  ( 0 ), ( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 ), ( 6 ), ( 7 ), ( 8 ), ( 9 )
  创建数字表



USE TSQL2012
GO
CREATE TABLE Nums
(
n INT NOT NULL PRIMARY KEY
);
  利用交叉联接在数字表中插入100万条数据



USE TSQL2012
GO
INSERT INTO dbo.Nums(n)
SELECT  D6.digit * 100000 + D5.digit * 10000 + D4.digit * 1000 + D3.digit * 100 + D2.digit * 10 + D1.digit + 1 AS n
FROM dbo.Digits AS D1
CROSS JOIN dbo.Digits AS D2
CROSS JOIN dbo.Digits AS D3
CROSS JOIN dbo.Digits AS D4
CROSS JOIN dbo.Digits AS D5
CROSS JOIN dbo.Digits AS D6
ORDER BY n
DSC0002.png


内部联接(INNER JOIN)
  内部联接用法如下



SELECT *
FROM table1 AS t1
INNER JOIN table2 AS  t2 ON t1.Id = t2.Id
内部联接返回表中更多数据
  我们首先给出如下三个测试表



USE TSQL2012
GO
CREATE TABLE FirstTable (Col1 INT)
CREATE TABLE SecondTable (Col1 INT)
CREATE TABLE ThirdTable (Col1 INT)
GO
INSERT INTO FirstTable (Col1)
VALUES (1), (2), (3), (NULL)
GO
INSERT INTO SecondTable (Col1)
VALUES (1), (2), (3), (NULL)
GO
INSERT INTO ThirdTable (Col1)
VALUES (2), (2), (2), (2), (2), (NULL)
GO
  (1)等值条件查询



SELECT f.Col1 fCol1
FROM FirstTable f
INNER JOIN SecondTable s ON s.Col1 = f.col1
GO
DSC0003.png

  (2)非等值条件查询



USE TSQL2012
GO
SELECT f.Col1 fCol1
FROM FirstTable f
INNER JOIN SecondTable s ON s.Col1 <> f.col1
GO
DSC0004.png

  上述我们同样可以利用交叉连接实现同样效果



USE TSQL2012
GO
SELECT f.Col1 fCol1
FROM FirstTable AS  f
CROSS JOIN SecondTable AS s
where s.Col1 <> f.col1
GO
  (3)查询非重复行(NON-DISTINCT)
  我们在创建第三个测试表时,插入的数据是5个2,而在第一个表中插入的数据分别是1、2、3,此时我们利用等值联接得到的结果到底是1个2,还是5个2呢?



USE TSQL2012
GO
SELECT f.Col1 fCol1
FROM FirstTable f
INNER JOIN ThirdTable s ON s.Col1 = f.col1
GO
DSC0005.png

  我们得到的结果是5个2,为什么利用内部联接也就是说利用的等值条件不是返回1个2呢,其实我们可以总结如下:
  结论:利用内部联接比实际表中返回更多数据的原因在于,内部联接返回的结果集是基于查询条件中的JOIN,若有多行满足条件则返回多条数据。

内部联接安全性
  在两个表利用等值条件查询时,我们有两种写法。
  ANSI SQL-92写法



USE TSQL2012
GO
SELECT *
FROM Sales.Orders AS SO
INNER JOIN Sales.OrderDetails AS SOD ON SOD.orderid = SO.orderid
  ANSI SQL-89写法



USE TSQL2012
GO
SELECT *
FROM Sales.Orders AS SO, Sales.OrderDetails AS SOD
WHERE SOD.orderid = SO.orderid
  虽然这两种写法都可以,都能满足需求,但是SQL Server 2012基础教程强烈建议使用ANSI SQL-92写法,为什么呢,因为用ANSI SQL-89写法时若出现错误,此时解析根本不会生成错误,而对于ANSI SQL-92写法则会,下面我们一起来看下ANSI SQL-89写法的问题



USE TSQL2012
GO
SELECT COUNT(*) AS '利用等值条件查询总数据行'
FROM Sales.Orders AS SO, Sales.OrderDetails AS SOD
WHERE SOD.orderid = SO.orderid
DSC0006.png

  上面是我们利用正确的写法得到的正确的总数据行为2155条,下面我们看看有问题的写法



SELECT COUNT(*) AS '利用等值条件查询总数据行'
FROM Sales.Orders AS SO, Sales.OrderDetails AS SOD
DSC0007.png

  此时我们没有给出WHERE条件,而解析未出现错误,当然返回的结果集也就是错误的。当我们利用ANSI SQL-92写法时,我们同样也未给出比较条件,如下



USE TSQL2012
GO

SELECT *
FROM Sales.Orders AS SO
INNER JOIN Sales.OrderDetails AS SOD;
DSC0008.png

  此时会出现解析错误,也就是无法再继续查询,自然也就得不到错误的结果。
  结论:强烈推荐使用ANSI SQL-92写法,这样一来使得数据不会出现不一致性,同时可读性和可维护性比ANSI SQL-89写法高。

总结
  本节我们讲了交叉联接和内部联接,同时也给出了使用需要注意的地方,本节到此结束,我们下节再讲讲自联接和外部联接。简短的内容,深入的理解,我们下节再会,good night。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393363-1-1.html 上篇帖子: SQL server学习 下篇帖子: sql server 常用的扩展存储过程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表