第三章.SQL联接

交叉联接

语法

SELECT 
	C.custid,
	E.empid
FROM Sales.Customers AS C
	CROSS JOIN HR.Employees AS E
--ANSI SQL-92语法

SELECT
	C.custid,
	E.empid
FROM Sales.Customers AS C,HR.Employees AS E
--ANSI SQL-89语法
--两者之间没有逻辑或性能差异,但建议使用ANSI SQL-92语法

自交叉联接

SELECT 
	E1.empid,E1.firstname,E1.lastname,
	E2.empid,E2.firstname,E2.lastname
FROM HR.Employees AS E1
	CROSS JOIN HR.Employees AS E2

生成数字表

SELECT 
	1 + D1.digit*100 + D2.digit + D3.digit * 10 AS N
FROM dbo.Digits AS D1
	CROSS JOIN dbo.Digits AS D2
	CROSS JOIN dbo.Digits AS D3

内部联接

--ANSI SQL-92
SELECT
	E.empid,E.firstname,E.lastname,
	O.orderid
FROM HR.Employees AS E
JOIN Sales.Orders AS O
ON E.empid = O.empid
--内部联接,应在表名称之间指定INNER JOIN关键词,由于内部联接是默认是内部联接所以INNER可以省略

--ANSI SQL-89
SELECT
	E.empid,E.firstname,E.lastname,
	O.orderid
FROM HR.Employees AS E
JOIN Sales.Orders AS O
WHERE E.empid = O.empid

内部联接安全性

推荐使用ANSI-SQL 92

更多联接示例

复合联接

SELECT
	OD.orderid,OD.productid,OD.qty,
	ODA.dt,ODA.loginname,ODA.oldval,ODA.newval
FROM Sales.OrderDetails AS OD
	JOIN Sales.OrderDetailsAudit AS ODA
	ON OD.orderid = ODA.orderid
	AND OD.productid = ODA.productid
WHERE ODA.columnname = N'qty';

不等联接

--不等联接就是联接条件涉及除等号以外的任何运算符
SELECT
	E1.empid,E1.firstname,E1.lastname,
	E2.empid,E2.firstname,E2.lastname
FROM HR.Employees AS E1
	JOIN HR.Employees AS E2
	ON E1.empid < E2.empid

多联接查询

--下面查询联接Customer和Orders表以匹配客户的订单
--然后以第一个联接的结果和OrderDetails表以匹配订单的订单行
SELECT
	C.custid,C.companyname,O.orderid,
	OD.productid,OD.qty
FROM Sales.Customers AS C
	JOIN Sales.Orders AS O
	ON C.custid = O.custid
	JOIN Sales.OrderDetails AS OD
	ON O.orderid = OD.orderid

外部联接

LEFT OUTER JOIN在两张表进行连接查询时,会返回左表所有的行,即使右表中没有匹配的记录,右表符合ON或者WHERE下的条件。

RIGHT OUTER JOIN在两张表进行连接查询时,会返回右表所有的行,即使左表中没有匹配的记录,左表符合ON或者WHERE下的条件。

FULL OUTER JOIN两张表同时符合ONWHERE下的条件。

SELECT
	C.custid,C.companyname,
	O.custid
FROM Sales.Customers AS C
LEFT OUTER JOIN Sales.Orders AS O
ON C.custid = O.custid

第一阶段:FROM

第二阶段:ON

第三阶段:... OUTER JOIN

第四阶段:WHERE

练习

--3.6.1
SELECT
	empid,firstname,lastname,n
FROM HR.Employees JOIN dbo.Nums 
ON n <= 5

--3.6.3
SELECT
	O.custid,COUNT(DISTINCT OD.orderid) AS numbers,SUM(qty) AS totalqty
FROM Sales.Customers AS C JOIN Sales.Orders AS O 
		ON C.country = 'USA' AND C.custid = O.custid
	 JOIN Sales.OrderDetails OD ON O.orderid = OD.orderid
GROUP BY O.custid

--3.6.4
SELECT
	C.custid,companyname,orderid,orderdate
FROM Sales.Customers AS C LEFT JOIN Sales.Orders AS D 
	ON C.custid = D.custid

--3.6.5
SELECT
	C.custid,companyname,orderid,orderdate
FROM Sales.Customers AS C LEFT JOIN Sales.Orders AS D 
	ON C.custid = D.custid
WHERE orderid IS NULL

--3.6.6
SELECT
	*
FROM Sales.Customers AS C JOIN Sales.Orders AS O 
	ON orderdate = '20070212' AND C.custid = O.custid;

--3.6.7
SELECT
	C.custid,companyname,
	CASE WHEN o.orderid IS NULL THEN 'NO'
	ELSE 'YES'
	END AS HasORderOn20070212
FROM Sales.Customers AS C LEFT OUTER JOIN Sales.Orders AS O 
	ON O.custid = C.custid AND orderdate = '20070212';
发布了85 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/WX_1218639030/article/details/104204716