SQLServer TOP(Transact-SQL)

1、本文内容

  • 语法
  • 参数
  • 最佳实践
  • 兼容性支持
  • 互操作性
  • 限制和局限
  • 示例

适用于:

  • Microsoft Fabric Microsoft Fabric
  • Warehouse 中的 SQL Server
  • Azure SQL 数据库
  • Azure SQL 托管实例
  • Azure Synapse
  • Analytics Analytics Platform System (PDW)
  • SQL Analytics 终结点

将在查询结果集中返回的行数限制到 SQL Server 中的指定行数或行的百分比。 将 TOP 用于 ORDER BY 子句时,结果集被限制为前 N 个已排序的行。 否则,TOP 将以未定义的顺序返回前 N 行。 使用此子句来指定从 SELECT 语句返回的行数。 或者,使用 TOP 来指定受 INSERT、UPDATE、MERGE 或 DELETE 语句影响的行。

参考官方文档地址如下
https://learn.microsoft.com/en-us/sql/t-sql/queries/top-transact-sql?view=sql-server-ver16

2、语法

以下为 SQL Server 和 Azure SQL 数据库的语法:

[   TOP (expression) [PERCENT]  [ WITH TIES ]  
]

以下是 Azure Synapse Analytics 和 Analytics Platform System (PDW) 的语法:

[   TOP ( expression )   [ WITH TIES ]  
]

3、参数

  • expression
    指定要返回的行数的数值表达式。 如果指定 PERCENT,expression 会隐式转换为 float 值。 否则,expression 会转换为 bigint。

  • PERCENT
    指示查询只返回结果集中前 expression% 的行。 小数部分的值向上舍入到下一个整数值。

  • WITH TIES
    返回与有限结果集中的最后一个位置相关联的两行或更多行。 必须将此参数用于 ORDER BY 子句。 WITH TIES 可能会导致返回的行数多于在 expression 中指定的值。 例如,如果 expression 设置为 5,而 2 个其他行与第 5 行中 ORDER BY 列的值匹配,则结果集将包含 7 行。

    仅当还指定了 ORDER BY 子句时,可以使用 WITH TIES 参数仅在 SELECT 语句中指定 TOP 子句。 返回的记录关联顺序是任意的。 ORDER BY 不影响此规则。

4、最佳实践

在 SELECT 语句中,始终将 ORDER BY 子句与 TOP 语句结合使用。 因为它是以可预知的方式指明哪些行受 TOP 影响的唯一方法。

在 ORDER BY 子句中使用 OFFSET 和 FETCH,而不使用 TOP 子句,以实现查询分页解决方案。 使用 OFFSET 和 FETCH 子句更容易实现分页解决方案(也即,将数据块或页发送到客户端)。 有关详细信息,请参阅 ORDER BY 子句 (Transact-SQL)。
https://learn.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-ver16

使用 TOP(或 OFFSET 和 FETCH)而非 SET ROWCOUNT 限制返回的行数。 这些方法之所以优于使用 SET ROWCOUNT,原因包括以下各项:

作为 SELECT 语句的一部分,查询优化器在查询优化期间可能会考虑 TOP 或 FETCH 子句中 expression 的值。 由于在运行查询的语句外部使用 SET ROWCOUNT,不会在查询计划中考虑它的值。

5、兼容性支持

为实现后向兼容性,如果表达式是整数常数,则括号在 SELECT 语句中是可选的。 我们建议在 SELECT 语句中始终为 TOP 使用括号。 这样做可与要求在 INSERT、UPDATE、MERGE 和 DELETE 语句中使用它的做法保持一致。

6、互操作性

TOP 表达式不影响由于触发器而可能运行的语句。 触发器中的 inserted 和 deleted 表将只返回确实受 INSERT、UPDATE、MERGE 或 DELETE 语句影响的那些行。 例如,INSERT TRIGGER 因使用 TOP 子句的 INSERT 语句而激发。

SQL Server 允许通过视图更新行。 由于可在视图定义中包含 TOP 子句,如果更新后行不再符合 TOP 表达式的要求,则某些行可能会从视图中消失。

如果在 MERGE 语句中指定,TOP 子句会在整个源表和整个目标表联接后应用。 而且,不符合执行插入、更新或删除操作要求的联接行会被删除。 TOP 子句将联接行的数量进一步减少为指定值,并且以一种无序方式对其余联接行应用插入、更新或删除操作。 也就是说,在 WHEN 子句中定义的操作中,这些行是无序分布的。 例如,如果指定 TOP (10) 会影响这些行中的 10 行,则 7 行可能会更新,3 行可能会插入。 或者,1 行可能会删除、5 行可能会更新以及 4 行可能会插入,以此类推。 由于 MERGE 语句对源表和目标表都进行完全表扫描,在使用 TOP 子句通过创建多个批处理来修改大型表时,I/O 性能可能会受到影响。 在这种情况下,请务必要确保所有连续批处理都以新行为目标。

在包含 UNION、UNION ALL、EXCEPT 或 INTERSECT 运算符的查询中指定 TOP 子句时,应特别小心。 此时可以编写一个返回意外结果的查询,因为当在选择操作中使用这些运算符时,以逻辑方式处理 TOP 和 ORDER BY 子句的顺序并不总是直观的。 例如,给定以下表和数据,假定您要返回最便宜的红色汽车和最便宜的蓝色汽车。 也就是红色的小轿车和蓝色的货车。

CREATE TABLE dbo.T_Cars(Model VARCHAR(15), Price MONEY, Color VARCHAR(10));  
INSERT dbo.T_Cars VALUES  ('sedan', 10086, 'red'), ('convertible', 15600, 'blue'),   ('coupe', 20097, 'red'), ('van', 8800, 'blue');SELECT * FROM dbo.T_Cars
GOModel           Price                 Color
--------------- --------------------- ----------
sedan           10086.00              red
convertible     15600.00              blue
coupe           20097.00              red
van             8800.00               blue(4 行受影响)
--为了实现这些结果,您可能会编写以下查询
SELECT TOP(1) Model, Color, Price  
FROM dbo.T_Cars
WHERE Color = 'red'  
UNION ALL  
SELECT TOP(1) Model, Color, Price  
FROM dbo.T_Cars
WHERE Color = 'blue'  
ORDER BY Price ASC;  
GO
-- result
Model           Color      Price
--------------- ---------- ---------------------
sedan           red        10086.00
convertible     blue       15600.00(2 行受影响)

此时返回意外结果,因为从逻辑上讲,会先运行 TOP 子句,然后运行 ORDER BY 子句,这会对运算符(在这种情况下为 UNION ALL)的结果进行排序。 因此,前一个查询返回任何一辆红色汽车和任何一辆蓝色汽车,然后按价格对该联合的结果排序。 下面的示例显示了编写此查询以获得所需结果的正确方法。

SELECT Model, Color, Price  
FROM (SELECT TOP(1) Model, Color, Price  FROM dbo.T_CarsWHERE Color = 'red'  ORDER BY Price ASC) AS a  
UNION ALL  
SELECT Model, Color, Price  
FROM (SELECT TOP(1) Model, Color, Price  FROM dbo.T_CarsWHERE Color = 'blue'  ORDER BY Price ASC) AS b;  
GO

通过在嵌套 select 操作中使用 TOP 和 ORDER BY,可确保将 ORDER BY 子句的结果应用于 TOP 子句,而不对 UNION 运算的结果排序。

Model           Color      Price
--------------- ---------- ---------------------
sedan           red        10086.00
van             blue       8800.00(2 行受影响)

6、示例

6.1、使用 TOP 以及一个常量值

下面的示例使用常量值以指定在查询结果集中返回的员工数。 在第一个示例中,返回前 10 个未定义的行,因为此时没有使用 ORDER BY 子句。 在第二个示例中,使用了 ORDER BY 子句来返回前 10 个最近雇用的员工。

USE AdventureWorks2022;  
GO  
-- Select the first 10 random employees.  
SELECT TOP(10)JobTitle, HireDate FROM HumanResources.Employee;  
GO  
-- Select the first 10 employees hired most recently.  
SELECT TOP(10)JobTitle, HireDate FROM HumanResources.Employee ORDER BY HireDate DESC;  
GO

6.2、使用 TOP 以及一个变量

下面的示例使用变量以指定在查询结果集中返回的员工数。

USE AdventureWorks2022;  
GO  
DECLARE @p AS INT = 10;  
SELECT TOP(@p)JobTitle, HireDate, VacationHours  
FROM HumanResources.Employee  
ORDER BY VacationHours DESC;  
GO

6.3、指定百分比

下面的示例使用 PERCENT 以指定在查询结果集中返回的员工数。 HumanResources.Employee 表中有 290 名员工。 因为 290 的 5% 是一个小数值,该值会向上舍入为下一个整数。

USE AdventureWorks2022;  
GO  
SELECT TOP(5)PERCENT JobTitle, HireDate  
FROM HumanResources.Employee  
ORDER BY HireDate DESC;  
GO

6.4、使用 WITH TIES 以包含与最后一行中的值匹配的行

以下示例获取所有雇员中薪金最高的 10 个百分比的雇员,并根据其薪金按降序返回。 指定 WITH TIES 可确保结果集中同时包含其薪金与返回的最低薪金(最后一行)相同的所有雇员,即使这样做会超过雇员总数的 10 个百分比

USE AdventureWorks2022;  
GO  
SELECT TOP(10) PERCENT WITH TIES  
pp.FirstName, pp.LastName, e.JobTitle, e.Gender, r.Rate  
FROM Person.Person AS pp   INNER JOIN HumanResources.Employee AS e ON pp.BusinessEntityID = e.BusinessEntityID  INNER JOIN HumanResources.EmployeePayHistory AS r ON r.BusinessEntityID = e.BusinessEntityID  
ORDER BY Rate DESC;  
GO

6.5、使用 TOP 限制删除的行数

如果将 TOP (n) 子句用于 DELETE,将针对未定义的选定 n 行执行删除操作。 也即,DELETE 语句选择满足 WHERE 子句中定义的条件的任何数目 (n) 的行。 下面的示例从 20 表中删除其到期日期早于 2002 年 7 月 1 日的 PurchaseOrderDetail 行。

USE AdventureWorks2022;  
GO  
DELETE TOP (20)   
FROM Purchasing.PurchaseOrderDetail  
WHERE DueDate < '20020701';  
GO

如果想要使用 TOP 来删除按有意义的时间顺序排列的行,请在嵌套 select 语句中将 TOP 用于 ORDER BY。 下面的查询从 PurchaseOrderDetail 表中删除了其到期日期最早的 10 行。 为了确保仅删除 10 行,嵌套 Select 语句 (PurchaseOrderID) 中指定的列将成为表的主键。 如果指定列包含重复的值,则在嵌套 Select 语句中使用非键列可能会导致删除的行超过 10 个。

USE AdventureWorks2022;  
GO  
DELETE FROM Purchasing.PurchaseOrderDetail  
WHERE PurchaseOrderDetailID IN  (SELECT TOP 10 PurchaseOrderDetailID   FROM Purchasing.PurchaseOrderDetail   ORDER BY DueDate ASC);  
GO

6.6、使用 TOP 限制插入的行数

以下示例创建 EmployeeSales 表,并插入 HumanResources.Employee 表中的前 5 名雇员的姓名和本年度到目前为止的销售数据。 INSERT 语句选择由满足 WHERE 子句中定义的条件的 SELECT 语句返回的任意 5 行。 OUTPUT 子句将显示插入 EmployeeSales 表中的行。 请注意,SELECT 语句中的 ORDER BY 子句不用于确定前 5 名雇员。

USE AdventureWorks2022;  
GO  
IF OBJECT_ID ('dbo.EmployeeSales', 'U') IS NOT NULL  DROP TABLE dbo.EmployeeSales;  
GO  
CREATE TABLE dbo.EmployeeSales  
( EmployeeID   NVARCHAR(11) NOT NULL,  LastName     NVARCHAR(20) NOT NULL,  FirstName    NVARCHAR(20) NOT NULL,  YearlySales  MONEY NOT NULL  );  
GO  
INSERT TOP(5)INTO dbo.EmployeeSales  OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales  SELECT sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD   FROM Sales.SalesPerson AS sp  INNER JOIN Person.Person AS c  ON sp.BusinessEntityID = c.BusinessEntityID  WHERE sp.SalesYTD > 250000.00  ORDER BY sp.SalesYTD DESC;  
GO
-- INSERT TOP(5) 。。。 执行,output子句返回结果如下
EmployeeID  FirstName            LastName             YearlySales
----------- -------------------- -------------------- ---------------------
274         Stephen              Jiang                559697.5639
275         Michael              Blythe               3763178.1787
276         Linda                Mitchell             4251368.5497
277         Jillian              Carson               3189418.3662
278         Garrett              Vargas               1453719.4653(5 行受影响)

如果想要使用 TOP 来插入按有意义的时间顺序排列的行,请在嵌套 select 语句中将 TOP 用于 ORDER BY。 下面的示例演示如何执行此操作。 OUTPUT 子句将显示插入 EmployeeSales 表中的行。 请注意,现在基于 ORDER BY 子句的结果(而非未定义的行)插入前 5 名雇员。

INSERT INTO dbo.EmployeeSales  OUTPUT inserted.EmployeeID, inserted.FirstName, inserted.LastName, inserted.YearlySales  SELECT TOP (5) sp.BusinessEntityID, c.LastName, c.FirstName, sp.SalesYTD   FROM Sales.SalesPerson AS sp  INNER JOIN Person.Person AS c  ON sp.BusinessEntityID = c.BusinessEntityID  WHERE sp.SalesYTD > 250000.00  ORDER BY sp.SalesYTD DESC;  
GO

6.7、使用 TOP 限制更新的行数

以下示例使用 TOP 子句更新表中的行。 如果将 TOP (n) 子句用于 UPDATE,将针对未定义数量的行运行更新操作。 也即,UPDATE 语句选择满足 WHERE 子句中定义的条件的任何数目 (n) 的行。 下列示例将 10 个客户从一位销售人员分配给了另一位。

USE AdventureWorks2022;  
UPDATE TOP (10) Sales.Store  SET SalesPersonID = 276 WHERE SalesPersonID = 275;  
GO

如果需要使用 TOP 来应用按有意义的时间顺序排列的更新,您必须同时使用 TOP 和 ORDER BY 子句。 下列示例更新了雇佣最早的 10 名雇员的假期小时数。

UPDATE HumanResources.Employee  
SET VacationHours = VacationHours + 8  
FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee  ORDER BY HireDate ASC) AS th  
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;  
GO

7、Azure Synapse Analytics 和 Analytics Platform System (PDW)

下列示例将返回匹配查询条件的前 31 行。 ORDER BY 子句可确保所返回的 31 行是按字母顺序排序的 LastName 列的前 31 行。

使用 TOP,且不指定关联。

SELECT TOP (31) FirstName, LastName   
FROM DimEmployee ORDER BY LastName;

结果:返回 31 行。

使用 TOP,并指定 WITH TIES。

SELECT TOP (31) WITH TIES FirstName, LastName   
FROM DimEmployee ORDER BY LastName;

结果:返回 33 行,因为有 3 名名为 Brown 的员工与第 31 行相关联。

备注:AdventureWorks2022测试库,请在如下地址下载
https://download.csdn.net/download/zxrhhm/89638395

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/53641.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中的数据一致性策略:从最终一致性到强一致性的选择

Java中的数据一致性策略&#xff1a;从最终一致性到强一致性的选择 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来讨论Java后端开发中非常重要的一个概念&#xff1a;数据一致性。数据…

MODELS 2024震撼续章:科技与可持续性的未来交响曲

MODELS 2024国际会议正如火如荼地进行着&#xff0c;每一天都充满了新的发现与启迪&#xff0c;每一场分享都是对技术前沿的一次深刻探索&#xff0c;更是对现实世界可持续性挑战的一次积极回应。现在让我们继续这场科技盛宴&#xff0c;看看小编为您精选几场的学术分享吧~ 会议…

地质工程专业职称申报条件详细解读

一、初级&#xff08;助理&#xff09;地质工程工程师评审条件&#xff1a; 1、理工类或者地质工程类专业毕业 2、专科毕业满3年或本科毕业满1年 3、研究生毕业&#xff0c;从事本专业技术工作&#xff0c;当年内考核认定 二、中级地质工程工程师评审条件&#xff1a; 1、理工…

【LeetCode刷题】链表篇

203. 移除链表元素 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }* }*…

每天一道面试题(18):Redis 和 MySQL 如何保证数据一致性

引言 在现代分布式系统中&#xff0c;Redis 常被用作缓存层以提升应用性能&#xff0c;而 MySQL 则作为持久化存储。然而&#xff0c;由于二者的数据存储特性不同&#xff0c;保证 Redis 和 MySQL 之间的数据一致性是一个重要且复杂的问题。在这篇学习笔记中&#xff0c;我们将…

大数据 flink 01 | 从零环境搭建 简单Demo 运行

什么是Flink Flink是一个开源的流处理和批处理框架,它能够处理无界和有界的数据流&#xff0c;具有高吞吐量、低延迟和容错性等特点 Flink 可以应用于多个领域如&#xff1a;实时数据处理、数据分析、机器学习、事件驱动等。 什么是流式处理&#xff1f;什么是批处理 流处理…

xQTLs 共定位分析(XQTLbiolinks包)

XQTL 共定位分析 XQTLbiolinks 是一个端到端的生物信息学工具&#xff0c;由深圳湾实验室李磊研究团队开发&#xff0c;用于高效地分析公共或用户定制的个xQTLs数据。该软件提供了一个通过与 xQTLs 共定位分析进行疾病靶基因发现的流程&#xff0c;以检测易感基因和致病变异。…

vimax通信协议

关于“Vimax通信协议”&#xff0c;实际上可能存在一定的误解或混淆。在通信技术和网络领域&#xff0c;并没有广泛认知的名为“Vimax”的通信协议。然而&#xff0c;您可能是在询问关于“WiMAX”的信息&#xff0c;因为“WiMAX”与“Vimax”在发音上相近&#xff0c;且WiMAX是…

【STM32】RTT-Studio中HAL库开发教程七:IIC通信--EEPROM存储器FM24C04

文章目录 一、简介二、模拟IIC时序三、读写流程四、完整代码五、测试验证 一、简介 FM24C04D&#xff0c;4K串行EEPROM&#xff1a;内部32页&#xff0c;每个16字节&#xff0c;4K需要一个11位的数据字地址进行随机字寻址。FM24C04D提供4096位串行电可擦除和可编程只读存储器&a…

python学习记录3

目录 1、数据类型转换 2、eval函数 3、运算符 1、数据类型转换 变量类型的转换分为隐类转换和显类转换&#xff0c;隐类转换在python代码行中运行时就自动发生。例如 x ture print(x1) 显类转换使用函数完成&#xff0c;主要有以下几种&#xff1a; x 10 #整数默认是i…

2.1 HuggingFists系统架构(一)

系统架构 HuggingFists的前端主体开发语言为HtmlJavascript&#xff0c;后端的主体开发语言为Java。在算子部分有一定份额的Python代码&#xff0c;用于整合Python在数据处理方面强大能力。 功能架构 HuggingFists的功能架构如上&#xff0c;由下向上各层为&#xff1a; 数据存…

leetcode刷题day29|贪心算法Part03( 134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列)

134. 加油站 思路&#xff1a; 暴力解法&#xff1a;for循环适合模拟从头到尾的遍历&#xff0c;while循环适合模拟环形遍历&#xff01;但是会超出leetcode的时间限制。 class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {for(int i0;i<gas.length…

从文本图片到多模态:3D 数字人打开企业全域商业增长新空间

摘要&#xff1a;数字化与AI浪潮推动各行业变革&#xff0c;内容形式也发生巨变&#xff0c;从文本到多媒体的多模态表达&#xff0c;标志着内容创造走向升维。AIGC 3D生成技术的突飞猛进&#xff0c;彻底打破了传统3D内容生产门槛高、周期长、成本高昂的问题。将3D数字人的打造…

若依 Vue3 前端分离 3.8.8 版实现去除首页,登录后跳转至动态路由的第一个路由的页面

一、前言 某些项目可能并不需要首页&#xff0c;但在若依中想要实现不显示首页&#xff0c;并根据不同角色登录后跳转至该角色的第一个动态路由的页面需要自己实现&#xff0c;若依中没有实现该功能的特定代码。 二、代码 1. src\permission.js 在 src\permission.js 中添加…

记录一下oceanbase数据库导出数据到mysql

导出 SQL 文件 使用 mysqldump 工具从 OceanBase 导出 SQL 文件到 output2222.sql。在这一步中&#xff0c;你需要确保你有正确的权限和数据库访问配置。 mysqldump -h 192.168.191.72 -P 2881 -u rootA_a -p密码 rhzfdb > output2222.sql清理 SQL 文件 使用 sed 命令批量…

VSCode编程配置再次总结

VScode 中C++编程再次总结 0.简介 1.配置总结 1.1 launch jsion文件 launch.json文件主要用于运行和调试的配置,具有程序启动调试功能。launch.json文件会启用tasks.json的任务,并能实现调试功能。 左侧任务栏的第四个选项运行和调试,点击创建launch.json {"conf…

探索 ShellGPT:终端中的 AI 助手

文章目录 探索 ShellGPT&#xff1a;终端中的 AI 助手背景介绍ShellGPT 是什么&#xff1f;如何安装 ShellGPT&#xff1f;简单的库函数使用方法场景应用常见问题及解决方案总结 探索 ShellGPT&#xff1a;终端中的 AI 助手 背景介绍 在当今快速发展的技术领域&#xff0c;命…

【TypeScript入坑】什么是TypeScript?

TypeScript入坑 什么是 TypeScriptTypeScript 的优势 什么是 TypeScript TypeScript&#xff1a;是 JavaScript 的超集&#xff0c;拥有类型机制&#xff0c;不会再浏览器直接执行&#xff0c;而是编译成 JavaScript 后才会运行。 超集&#xff08;superset&#xff09;&…

Redis中的setnx的使用场景

Redis中的SETNX命令是一个非常有用的工具&#xff0c;特别是在处理分布式系统和并发控制时。SETNX是“Set if Not Exists”的缩写&#xff0c;用于设置键的值&#xff0c;但仅当键不存在时。以下是SETNX命令的一些主要使用场景&#xff1a; 1. 分布式锁 在分布式环境中&#…

查询最近正在执行的sql(DM8 : 达梦数据库)

查询最近正在执行的sql DM8 : 达梦数据库 1 查询最近正在执行的sql2 更多达梦数据库学习使用列表 1 查询最近正在执行的sql 迁移数据时 , 业务无响应 , 查看最近活动的sql , 有没有迁移相关的表 , 通过最后的时间字段 , 判断会话是否正在执行 SELECT SESS_ID, SQL_TEXT, STATE…