SQL Server递归cte求助

时间:2012-03-04 13:41:09

标签: sql-server sql-server-2008-r2 common-table-expression

我正在尝试生成一个数据集,我认为递归是必需的,但我不能完全适应我发现的众多例子。我想要的最终结果很容易描述。

涉及两个表:第一个包含相关字段TradeDateSymbolClse(收盘价)的股票的交易定价,以及列出交易日的表格。我想按符号排序定价数据,按日期排序,但如果定价表中缺少交易日期,我希望分区/行编号中断,因为此数据来自一个Web服务,即有时候有点不可预测。

我的第一次尝试是一个简单的选择查询,它有一个WHERE子句,调用了我编写的udf来查看该符号/日期组合是否有连续数据。它工作(它运行)和我运行它的那个晚上,7个小时之后它几乎通过以'A'开头的符号。

修改
我的这篇帖子以及SO上的回复SQL server select query help for stored procedure needed在概念上是有帮助的,但我目前对这个概念的使用还需要更多(表连接,分区/行编号等)

如果它有助于理解问题,我想使用返回的内容来计算每个符号的各种聚合,使用过去数据点的交易日期组合。示例:符号/交易日期的收盘价的5期间移动平均值将是具有交易日期< =计算日期的五个收盘价(clse)的平均值。因此,使用下面第一个表中的示例数据,我想返回符号'A'的9.02,3个期间,交易日期1/3/12。如果其中一个计算缺少数据,我想要null。

我想要的结果集是一个简单的PARTITION选择查询,如果它不是为了检查缺少的日期。所以这里是所涉及的表的一些示例数据和我的目标结果集:

tblDailyPricingAndVol

TradeDate Symbol Clse
1/1/12    A      9.01
1/2/12    A      9.05
1/3/12    A      8.99
1/5/12    A      9.03
1/1/12    B      10.05
1/4/12    B      10.11
1/5/12    B      10.03

tblTradingDays

TradingDate
1/1/12
1/2/12
1/3/12
1/4/12
1/5/12

目标结果集:

RowNumber TradeDate Symbol Clse
1         1/1/12    A      9.01
2         1/2/12    A      9.05
3         1/3/12    A      8.99
1         1/5/12    A      9.03
1         1/1/12    B      10.05
1         1/4/12    B      10.11
2         1/5/12    B      10.03

希望这是有道理的。任何帮助,将不胜感激。我想如果我可以在我自己的数据上按预期运行,我会更清楚地看到递归cte。感谢。

2 个答案:

答案 0 :(得分:2)

我认为合并dense_rank()row_number()可以在这里工作:

; with cte as (
    select d.TradingDate,p.Symbol,p.Clse
    , r=DENSE_RANK()over(order by d.TradingDate)
    , r1=row_number()over(partition by p.Symbol order by p.TradeDate)
    from tblTradingDays d
    inner join tblDailyPricingAndVol p on d.TradingDate=p.TradeDate
)
select
RowNumber=row_number()over(partition by Symbol, (r-r1) order by TradingDate)
, TradingDate,Symbol,Clse
from cte
go

结果:

enter image description here

答案 1 :(得分:1)

set dateformat mdy

declare @tblDailyPricingAndVol table
(
  TradeDate date,
  Symbol char(1),
  Clse money
)

insert into @tblDailyPricingAndVol values
('1/1/12',    'A',      9.01),
('1/2/12',    'A',      9.05),
('1/3/12',    'A',      8.99),
('1/5/12',    'A',      9.03),
('1/1/12',    'B',      10.05),
('1/4/12',    'B',      10.11),
('1/5/12',    'B',      10.03)

;with C as
(
  select TradeDate,
         Symbol,
         Clse,
         row_number() over(partition by Symbol order by TradeDate) as rn
  from @tblDailyPricingAndVol
)
select row_number() over(partition by Symbol, datediff(day, 0, TradeDate) - rn 
                         order by TradeDate) as RowNumber,
       TradeDate,
       Symbol,
       Clse
from C
order by Symbol, TradeDate