用于填充@Table列的游标(使用where子句)

时间:2014-02-20 19:10:58

标签: sql sql-server

我有一个程序根据日期范围操纵数据范围并以这种格式返回数据:

myDates     myDataResult
2012-05-02  0.0208
2012-05-03  -0.017
2012-05-04  -0.026
2012-05-07  -0.009
2012-05-08  -0.013
2012-05-09  0.006

我想到的是使用游标在选定的数据集(ID)上多次运行该过程,创建一个将输出组合成如下所示的表:

myDates     ID1     ID2     ID2
2012-05-02  0.208   0.384   -0.123   
2012-05-03  -0.017  0.578   0.134
2012-05-04  -0.026  -0.045  -0.234
2012-05-07  -0.009  0.567   0.056
2012-05-08  -0.013  -0.481  0.034
2012-05-09  0.006   -0.113  0.187

我一直在尝试一些游标代码而且我被困在这里:

Declare @TempTable Table(myDates Date,myDataresults Float)
Declare @IDc Int

DECLARE IDCursor CURSOR For

SELECT ID
FROM Top40_Key$ 
Where ID<5
Order by ID;

Open IDCursor
Fetch Next From IDCursor 
Into @IDc

While @@FETCH_STATUS=0
Begin

Insert @TempTable(myDates,myDataresults)
Execute pro_myReturnTimeSeries @begDate='2012/05/01',@endDate='2012/05/18',@ID1=@IDc
Fetch Next From IDCursor INTO @IDc
End

Close IDCursor
Deallocate IDCursor

Select * From @TempTable

光标是否必要?我知道它在SQL中是不是很理想。我使用的是SQL Server 2012。

编辑:如果有人可以在没有游标的情况下弄清楚如何执行此操作,那么这就是存储过程的外观:

[pro_myReturnTimeSeries] @begDate Date,@endDate Date, @ID1 Int

AS

Declare @prevDate Date

Set @prevdate = (Select Max(mydates) From Top40_Prices Where myDates<@begDate and       PrimID=@ID1)

Select * From
(Select T2.myDates,T2.Price/T1.Price-1 As myDataResult
From
(Select myDates,Price,ROW_NUMBER() Over(Order by myDates) as RowT2
From Top40_Prices
Where myDates Between @prevDate and @endDate
and PrimID=@ID1) T2

Left Join
(Select myDates,Price, ROW_NUMBER() Over(Order by myDates) as RowT1
From Top40_Prices
Where myDates Between @prevDate and @endDate
and PrimID=@ID1) T1

On
RowT2-1=RowT1) as Subquery

Where myDataResult is not null

2 个答案:

答案 0 :(得分:1)

如果您也可以让程序返回ID,那么您可以创建临时表,使其看起来像

Declare @TempTable Table(myDates Date,myDataresults Float,myId Int)

然后运行所有ID并创建一个大的@tempTable。您可以使用SQL Pivot命令在3个ID列之间传播值

答案 1 :(得分:1)

如果您可以重写pro_myReturnTimeSeries,则可以在没有光标的情况下执行此操作。但是,如果您只需要一个快速而肮脏的答案:(代码更改位于注释块内)

--####
Declare @TempTable Table(myDates Date,myDataresults Float, [ID] int)
--####
Declare @IDc Int

DECLARE IDCursor CURSOR For

SELECT ID
FROM Top40_Key$ 
Where ID<5
Order by ID;

Open IDCursor
Fetch Next From IDCursor 
Into @IDc

While @@FETCH_STATUS=0
Begin

Insert @TempTable(myDates,myDataresults)
Execute pro_myReturnTimeSeries @begDate='2012/05/01',@endDate='2012/05/18',@ID1=@IDc
--####
UPDATE @TempTable SET [ID] = @IDc WHERE [ID] IS NULL
--####
Fetch Next From IDCursor INTO @IDc
End

Close IDCursor
Deallocate IDCursor

--####  This defines which ids the labels "ID1",etc represent.
DECLARE @ResultID TABLE ([ID_code] sysname, [ID] int)
INSERT @ResultID VALUES
  ('ID1',1),
  ('ID2',4),
  ('ID3',5)

SELECT 
  [myDates], [ID1], [ID2], [ID3]
FROM @TempTable t1
INNER JOIN @ResultID t2 ON t1.[ID] = t2.[ID]
PIVOT(MAX(myDataresults) FOR [ID_code] IN ([ID1],[ID2],[ID3]) ) t3
--####