有这样一个帖子,有三个表
客户表
CREATE TABLE [dbo].[Test_Customer](
[ID] [int] IDENTITY(1,1) NOT NULL,
[CustomerName] [nvarchar](50) NULL
)
商品表
CREATE TABLE [dbo].[Test_Production](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ProductionName] [nvarchar](50) NULL,
[Price] [int] NULL
)
销售产品详细记录
CREATE TABLE [dbo].[Test_Relation](
[ID] [int] IDENTITY(1,1) NOT NULL,
[CustomerId] [int] NOT NULL,
[ProductionID] [int] NOT NULL,
[ProductionAmount] [int] NOT NULL
)
需求是这样的,在客户表里有N个客户,在商品表里有N个商品,销售详细记录是卖产品的记录,求每件产品的销售额前三的客户
网上查询的结果是
SELECT n.* FROM
(SELECT ProductionName from Test_Production) m
outer APPLY
(
SELECT TOP 1
b.ProductionName,
c.CustomerName,
销售额 = b.Price*a.ProductionAmount
FROM Test_Relation a
INNER JOIN Test_Production b
ON a.ProductionID = b.Id
INNER JOIN Test_Customer c
ON a.CustomerId = c.Id
WHERE b.ProductionName = m.ProductionName
ORDER BY 销售额 DESC
) n
这样会得到正确的结果。
这里的关键是用到了Apply函数。从msdn中看到的描述是这样的。
使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。APPLY 运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。
APPLY 有两种形式: CROSS APPLY 和 OUTER APPLY。CROSS APPLY 仅返回外部表中通过表值函数生成结果集的行。OUTER APPLY 既返回生成结果集的行,也返回不生成结果集的行,其中表值函数生成的列中的值为 NULL。
例如,考虑下列表 Employees 和 Departments
如下是个人的理解
apply会把上面的每个ProductionName和下面Apply里面的内容进行比较,相当于用游标里循环然后把结果集再拼到一起。
分为outer Apply 和Cross Apply,
out apply相当于左连接相当于m的所有
cross apply相当于内连接,取两个的合集
本文介绍如何使用 SQL 的 APPLY 函数解决复杂的查询需求,特别是针对多个表联接时的销售额排名问题。通过示例展示了 APPLY 的工作原理及两种形式:CROSS APPLY 和 OUTER APPLY,并解释了它们的区别。

602

被折叠的 条评论
为什么被折叠?



