SQL Server中怎么实现交叉联接和内部联接,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

交叉联接(CROSS JOIN)

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

SELECTC.custid,E.empidFROMSales.CustomersASCCROSSJOINHR.EmployeesASEORDERBYE.empid

在Sales.Customers表中有91行数据,HR.Employees表中有9行数据,则利用交叉联接数据则有819(91*9)行数据,简略数据如下。

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

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

IFOBJECT_ID('dbo.Digits','U')ISNOTNULLDROPTABLEdbo.Digits;CREATETABLEdbo.Digits(digitINTNOTNULL);

插入10条基础数据

USETSQL2012GOINSERTINTOdbo.Digits(digit)VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)

创建数字表

USETSQL2012GOCREATETABLENums(nINTNOTNULLPRIMARYKEY);

利用交叉联接在数字表中插入100万条数据

USETSQL2012GOINSERTINTOdbo.Nums(n)SELECTD6.digit*100000+D5.digit*10000+D4.digit*1000+D3.digit*100+D2.digit*10+D1.digit+1ASnFROMdbo.DigitsASD1CROSSJOINdbo.DigitsASD2CROSSJOINdbo.DigitsASD3CROSSJOINdbo.DigitsASD4CROSSJOINdbo.DigitsASD5CROSSJOINdbo.DigitsASD6ORDERBYn

内部联接(INNER JOIN)

内部联接用法如下

SELECT*FROMtable1ASt1INNERJOINtable2ASt2ONt1.Id=t2.Id

内部联接返回表中更多数据

我们首先给出如下三个测试表

USETSQL2012GOCREATETABLEFirstTable(Col1INT)CREATETABLESecondTable(Col1INT)CREATETABLEThirdTable(Col1INT)GOINSERTINTOFirstTable(Col1)VALUES(1),(2),(3),(NULL)GOINSERTINTOSecondTable(Col1)VALUES(1),(2),(3),(NULL)GOINSERTINTOThirdTable(Col1)VALUES(2),(2),(2),(2),(2),(NULL)GO

(1)等值条件查询

SELECTf.Col1fCol1FROMFirstTablefINNERJOINSecondTablesONs.Col1=f.col1GO

(2)非等值条件查询

USETSQL2012GOSELECTf.Col1fCol1FROMFirstTablefINNERJOINSecondTablesONs.Col1<>f.col1GO

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

USETSQL2012GOSELECTf.Col1fCol1FROMFirstTableASfCROSSJOINSecondTableASswheres.Col1<>f.col1GO

(3)查询非重复行(NON-DISTINCT)

我们在创建第三个测试表时,插入的数据是5个2,而在第一个表中插入的数据分别是1、2、3,此时我们利用等值联接得到的结果到底是1个2,还是5个2呢?

USETSQL2012GOSELECTf.Col1fCol1FROMFirstTablefINNERJOINThirdTablesONs.Col1=f.col1GO

我们得到的结果是5个2,为什么利用内部联接也就是说利用的等值条件不是返回1个2呢,其实我们可以总结如下:

结论:利用内部联接比实际表中返回更多数据的原因在于,内部联接返回的结果集是基于查询条件中的JOIN,若有多行满足条件则返回多条数据。

内部联接安全性

在两个表利用等值条件查询时,我们有两种写法。

ANSI SQL-92写法

USETSQL2012GOSELECT*FROMSales.OrdersASSOINNERJOINSales.OrderDetailsASSODONSOD.orderid=SO.orderid

ANSI SQL-89写法

USETSQL2012GOSELECT*FROMSales.OrdersASSO,Sales.OrderDetailsASSODWHERESOD.orderid=SO.orderid

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

USETSQL2012GOSELECTCOUNT(*)AS'利用等值条件查询总数据行'FROMSales.OrdersASSO,Sales.OrderDetailsASSODWHERESOD.orderid=SO.orderid

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

SELECTCOUNT(*)AS'利用等值条件查询总数据行'FROMSales.OrdersASSO,Sales.OrderDetailsASSOD

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

USETSQL2012GOSELECT*FROMSales.OrdersASSOINNERJOINSales.OrderDetailsASSOD;

关于SQL Server中怎么实现交叉联接和内部联接问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。