T-SQL中APPLY子句的用法详解

在使用sql进行多表查询时,我们经常使用到左连接(left join)来对左表进行扩展,此时,输入的左表和右表通过在两边指定字段进行匹配,如果指定的两个字段相等,则返回结果。逻辑上,我们可以理解为对左表进行一次基于行的遍历,为每一行在右表中找出匹配的所有行,返回结果集,最后将由左表每一行产生的结果集合并为最终的结果集;而apply的就好像是左连接的升级版本,只是这里的右表是函数或表达式,将左表中的每一行的某一字段或多个字段输入到右表进行一次运算,最后将所有结果集合并为最终结果集。
Apply又分为cross apply和outer apply两种,上面介绍了cross apply,outer apply相较于cross apply区别是:当右表返回的结果集是空集,cross apply不会返回左表的数据,而outer apply会返回左表的数据并将右表补为NULL。
下面给出示例:
现有两张表分别为种类表和产品表:
Categories

categroyidcategoryname
1Beverages
2Condiments
3Confections

Products

productidproductnamecategroyid
1Product HHYDP1
2Product RECZE1
24Product QOGNU1
3Product IMEHJ2
4Product KSBRM2
5Product EPEIM2
16Product PAFRH3
19Product XKXDO3
20Product QHFFP3

首先根据种类表找出所有属于种类表列出种类的产品,此时使用左连接和cross apply都可以实现。

/*LEFT JOIN*/
SELECT
	C.categoryid,
	C.categoryname,
	P.productid,
	P.productname
FROM
	[Production].[Categories] AS C
LEFT JOIN Production.Products P ON C.categoryid = P.categoryid
/*CROSS APPLY*/
SELECT
	C.categoryid,
	C.categoryname,
	P.productid,
	P.productname
FROM
	[Production].[Categories] AS C CROSS APPLY (
		SELECT
			productname,
			productid
		FROM
			Production.Products
		WHERE
			categoryid = C.categoryid
	) AS P

会发现两种写法得到的结果相同

categoryidcategorynameproductidproductname
1Beverages1Product HHYDP
1Beverages2Product RECZE
1Beverages24Product QOGNU
2Condiments3Product IMEHJ
2Condiments4Product KSBRM
2Condiments5Product EPEIM
3Confections16Product PAFRH
3Confections19Product XKXDO
3Confections20Product QHFFP

此时,如果在种类表中加一个种类,但是在产品表中却找不到该种类的产品,左连接会返回左表,为右表补NULL,而cross apply不会。此时就需要将cross apply改为outer apply以达到和左连接相同的结果:
Categories

categroyidcategoryname
1Beverages
2Condiments
3Confections
4Dairy Products

Result

categoryidcategorynameproductidproductname
1Beverages1Product HHYDP
1Beverages2Product RECZE
1Beverages24Product QOGNU
2Condiments3Product IMEHJ
2Condiments4Product KSBRM
2Condiments5Product EPEIM
3Confections16Product PAFRH
3Confections19Product XKXDO
3Confections20Product QHFFP
4Dairy Products
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值