Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从SQL Server游标返回单个行集?_Sql_Sql Server_Cursor_Tempdb - Fatal编程技术网

如何从SQL Server游标返回单个行集?

如何从SQL Server游标返回单个行集?,sql,sql-server,cursor,tempdb,Sql,Sql Server,Cursor,Tempdb,我在下面有一个查询,它在SQL Server中工作,用于选择一列中的值与另一列中的值之间的差异,但在源表的前面两行。源表有三列(PK bigint、Pv float、现金float) 当我使用这个查询时,我得到的是一系列单行行集,而不是一个大行集。我可以一个接一个地将它们插入临时表中,然后从中选择,但这意味着对于大型表,我最终会得到一个大型临时表以及返回第一条记录的长延迟 有没有办法将此查询的结果作为一个单行集有效地假脱机 declare @PK bigint declare @Pv float

我在下面有一个查询,它在SQL Server中工作,用于选择一列中的值与另一列中的值之间的差异,但在源表的前面两行。源表有三列(PK bigint、Pv float、现金float)

当我使用这个查询时,我得到的是一系列单行行集,而不是一个大行集。我可以一个接一个地将它们插入临时表中,然后从中选择,但这意味着对于大型表,我最终会得到一个大型临时表以及返回第一条记录的长延迟

有没有办法将此查询的结果作为一个单行集有效地假脱机

declare @PK bigint
declare @Pv float
declare @Cash float
declare @Cash_minus_1 float
declare @Cash_minus_2 float
set @Cash_minus_1 = 0
set @Cash_minus_2 = 0
declare myCursor cursor fast_forward
for select PK, Pv, Cash from MyTable order by PK
for read only
open myCursor
fetch next from myCursor
into @PK, @Pv, @Cash
while @@FETCH_STATUS = 0
begin
 select @PK, @Pv, @Cash, @Cash_minus_2
 set @Cash_minus_2 = @Cash_minus_1
 set @Cash_minus_1 = @Cash
 fetch next from myCursor
 into @PK, @Pv, @Cash
end
close myCursor
deallocate myCursor

使用
ROW\u NUMBER
函数按所需顺序为每一行分配数字(需要,因为PK可能有间隙,这会中断查询),并将表本身与-2行连接起来

WITH CTE AS 
(
    SELECT PK, Pv, Cash, ROW_NUMBER() OVER (ORDER BY PK) RN from MyTable
)
SELECT C.PK, C.Pv, C.Cash, C2.Cash AS Cash_Minus_2 
FROM CTE C
LEFT JOIN CTE C2 ON C.RN = C2.RN + 2
在SQL Server 2012中,甚至有一个窗口函数
LAG
可以直接使用

SELECT PK, Pv, Cash, LAG(Cash,2,NULL) OVER (ORDER BY PK) AS Cash_Minus_2
FROM MyTable

假设SQL Server 2005或更高版本,则可以使用和来适当排列表:

;With OrderedRows as (
    select PK, Pv, Cash,
        ROW_NUMBER() OVER (ORDER BY PK) as rn --Is this correct?
    from MyTable
)
select or1.PK,or1.Pv,or1.Cash,COALESCE(or2.Cash,0)
from
    OrderedRows or1
        left join
    OrderedRows or2
        or1.rn = or2.rn + 2
在上面,我假设
PK
定义了应该考虑行的顺序,这样您的问题中的“提前两行”就更有意义了



一般来说,游标应该被视为最后的工具。首先,您应该始终尝试制定查询,讨论整个结果集应该是什么样子,而不是您(如果必须)将如何逐行计算出来。

“两行之前”-由于您的
选择
没有
ORDER by
子句,这也可以指定为“来自表中的其他随机行”。如果您能告诉我们哪些列应该定义顺序,那么“实际上是有道理的,我们也应该能够提供帮助,你能说一下你使用的是什么版本的SQL Server吗?@Damien_The_unsiver 2008 R2。是的,请注意,查询中未定义行顺序,我们试图尽可能简化示例-已编辑示例查询。请注意有关光标使用的警告,但假设我有一个很好的理由需要逐行处理结果集(这个问题背后的真正查询要复杂得多,不适合自连接方法)。我想我的问题是,我是否可以将这个查询的结果作为一个行集返回,而不是我是否可以以更有效的方式重新编写这个简单的示例查询。@JonG-不,没有办法(除了您已经绘制的临时表/表变量暂存区域)要从多个SQL语句中生成属于同一结果集的多个行感谢您的响应,我感谢您可以使用其他表单重新编写此查询,但我在这里特别询问如何从游标查询返回结果行。