使用排名和行集函数
排名和行集函数不是标量函数,因为它们不返回单个值。 这些函数接受一组行作为输入,并将一组行作为输出返回。
排名函数
排名函数允许针对用户定义的行集执行计算。 这些函数包括排名、偏移量、聚合和分布函数。
此示例使用 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
按价格排序
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
按价格排序
背带短裤
男子背带短裤,S码
89.99
1
背带短裤
Men's Bib-Shorts, M
89.99
1
自行车车架
Hitch Rack - 4-Bike
120
1
单车存放架
All-Purpose 自行车停放架
159
1
瓶子和笼子
Mountain Bottle Cage
9.99
1
瓶子和笼子
Road Bottle Cage
8.99
2
瓶子和笼子
水瓶 - 30 盎司。
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 参考文档。