使用排名和行集函数
排名和行集函数不是标量函数,因为它们不会返回单个值。 这些函数接受一组行作为输入,并返回一组行作为输出。
排名函数
排名函数可用于针对用户定义的行集执行计算。 这些函数包括排名、偏移量、聚合和分布函数。
本示例使用 RANK 函数根据 ListPrice 计算排名,最高价格排名为 1:
SELECT TOP 100 ProductID, Name, ListPrice,
RANK() OVER(ORDER BY ListPrice DESC) AS RankByPrice
FROM Production.Product AS p
ORDER BY RankByPrice;
查询结果可能如下所示:
ProductID
名称
ListPrice
RankByPrice
749
Road-150 Red, 62
3578.27
1
750
Road-150 Red, 44
3578.27
1
751
Road-150 Red, 48
3578.27
1
771
Mountain-100 Silver, 38
3399.99
4
772
Mountain-100 Silver, 42
3399.99
4
775
Mountain-100 Black, 38
3374.99
6
...
...
...
...
OVER
可以使用 OVER 子句来定义分区或数据中的分组。 例如,以下查询扩展了前面的示例,可计算每个类别中产品的基于价格的排名。
SELECT c.Name AS Category, p.Name AS Product, ListPrice,
RANK() OVER(PARTITION BY c.Name ORDER BY ListPrice DESC) AS RankByPrice
FROM Production.Product AS p
JOIN Production.ProductCategory AS c
ON p.ProductCategoryID = c.ProductcategoryID
ORDER BY Category, RankByPrice;
此查询的结果可能如下所示:
类别
产品
ListPrice
RankByPrice
骑行背带短裤
Men's Bib-Shorts, S
89.99
1
骑行背带短裤
Men's Bib-Shorts, M
89.99
1
自行车车架
Hitch Rack - 4-Bike
120
1
单车存放架
All-Purpose Bike Stand
159
1
瓶子和笼子
Mountain Bottle Cage
9.99
1
瓶子和笼子
Road Bottle Cage
8.99
2
瓶子和笼子
Water Bottle - 30 oz.
4.99
3
底托架
HL Bottom Bracket
121.49
1
底托架
ML Bottom Bracket
101.24
2
底托架
LL Bottom Bracket
53.99
3
...
...
...
...
注意
请注意,多个行具有相同排名值,并且会跳过一些值。 这是因为我们只使用了 RANK。 根据要求,你可能希望避免具有相同排名值的情况。 可以根据需要使用其他函数(DENSE_RANK、NTILE 和 ROW_NUMBER)来控制排名值。 有关这些函数的详细信息,请参阅 Transact-SQL 参考文档。
行集函数
行集函数返回一个虚拟表,该虚拟表可以在 FROM 子句中用作数据源。 这些函数使用特定于行集函数本身的参数。 这些函数包括 OPENDATASOURCE、OPENQUERY、OPENROWSET、OPENXML 和 OPENJSON。
OPENDATASOURCE、OPENQUERY 和 OPENROWSET 函数可以将查询传递给远程数据库服务器。 然后,远程服务器将返回一组结果行。 例如,以下查询使用 OPENROWSET 从名为 SalesDB 的 SQL Server 实例获取查询的结果。
SELECT a.*
FROM OPENROWSET('SQLNCLI', 'Server=SalesDB;Trusted_Connection=yes;',
'SELECT Name, ListPrice
FROM AdventureWorks.Production.Product') AS a;
要使用远程服务器,必须在运行查询的 SQL Server 实例中启用一些高级选项。
OPENXML 和 OPENJSON 函数能够以 XML 或 JSON 格式查询结构化数据,并能够将值提取到表格行集。
行集函数的详细介绍不属于本模块的范围。 有关详细信息,请参阅 Transact-SQL 参考文档。