前言
本节开始我们进入联接学习,关于连接这一块涉及的内容比较多,我们一步一步循序渐进学习,简短内容,深入的理解,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)行数据,简略数据如下。
交叉联接我们可以用如下图表示
交叉联接最大的用途在于生成数字表以便我们用于其他目的,我们一起来看看。
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
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
内部联接(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
(2)非等值条件查询
USE TSQL2012
GO
SELECT f.Col1 fCol1
FROM FirstTable f
INNER JOIN SecondTable s ON s.Col1 <> f.col1
GO
上述我们同样可以利用交叉连接实现同样效果
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
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
上面是我们利用正确的写法得到的正确的总数据行为2155条,下面我们看看有问题的写法
SELECT COUNT(*) AS '利用等值条件查询总数据行'
FROM Sales.Orders AS SO, Sales.OrderDetails AS SOD