您没有提及您使用的是哪个 SQL Server 版本。如果是 2012+,您可以使用 LAG() 和 LEAD() 函数来快速实现:
滞后:
访问同一结果集中前一行的数据,不带
在 SQL Server 2012+ 中使用自联接。 LAG 提供对行的访问
在当前行之前的给定物理偏移量处。用这个
SELECT 语句中的分析函数来比较
当前行的值在前一行中。
领导:
访问同一结果集中后续行中的数据,不带
在 SQL Server 2012+ 中使用自联接。 LEAD 提供对行的访问
在当前行之后的给定物理偏移量处。用这个
SELECT 语句中的分析函数来比较
当前行的值在下一行。
这是一个例子:
DECLARE @Test TABLE
(
ID INT
);
INSERT INTO @Test
VALUES (12)
, (34)
, (76)
, (89)
, (1234)
, (1254)
, (6789)
, (3456);
;WITH CTE (ID, Prev, Next, Extreme)
AS (
SELECT ID
, LAG(ID) OVER (ORDER BY (SELECT NULL))
, LEAD(ID) OVER (ORDER BY (SELECT NULL))
, MAX(ID) OVER ()
FROM @Test
)
SELECT *
FROM CTE
WHERE ID = 1234;
这个查询返回
╔══════╦══════╦══════╦═════════╗
║ ID ║ Prev ║ Next ║ Extreme ║
╠══════╬══════╬══════╬═════════╣
║ 1234 ║ 89 ║ 1254 ║ 6789 ║
╚══════╩══════╩══════╩═════════╝
正如 lad2025 所说,如果 sql server 优化器决定使用并行性,这个查询以及已回答的查询将会中断。
使用OPTION(MAXDOP 1) 提示可能会解决它。它告诉 sql server 不要使用并行性。唯一正确的方法是拥有列,您可以为您的数据集提供稳定的顺序。