【问题标题】:SQL Server recursive cte help wantedSQL Server递归cte帮助需要
【发布时间】:2012-03-04 13:41:08
【问题描述】:

我正在尝试生成一个数据集,我认为递归是必需的,但我无法完全根据我的目的调整我找到的众多示例。我想要的最终结果很容易描述。

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

我的第一次尝试是一个足够简单的选择查询,它有一个 WHERE 子句,我写了一个名为 udf 的子句,以查看该符号/日期组合是否有连续数据。它起作用了(它运行了),在我运行它的那天晚上,7 小时后它几乎通过了以“A”开头的符号。

编辑
我的这篇文章和不久前关于 SO 的SQL server select query help for stored procedure needed 的回复在概念上很有帮助,但我目前对该概念的使用需要更多(表连接、分区/行编号等)

如果它有助于理解问题,我想使用返回的数据来计算每个交易品种的各种聚合,使用过去数据点的交易日期组合。示例:交易品种/交易日期收盘价的 5 个周期移动平均线将是交易日期

如果不需要检查缺失的日期,我想要的这个结果集将是一个简单的 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。谢谢。

【问题讨论】:

  • 我认为递归 CTE 在这里没有帮助。您需要的是 lag 窗口函数。但是 SQL Server 还不支持。
  • @a_horse_with_no_name 真的吗?也许我确实对递归 cte 有很好的掌握,因为我看不出它在这个应用程序中是如何工作的。没听说过延迟。也许我需要一个游标和一个更程序化的代码类型的存储过程。
  • lag 是一个标准的窗口函数,可让您访问前行的列值。
  • 您可以按Symbol 进行分区 - 但随后您会得到1, 2, 3, 4 的符号A - 行号不会在分区中间重新启动。或者您可以按Symbol, TradeDate 进行分区 - 但随后您将获得每个日期的连续编号。用 T-SQL 来满足你的要求真的很难(如果不是不可能的话)
  • @marc_s 这正是我所处的位置......如果没有必要处理丢失的数据点,可以轻松分区。我将编辑我的帖子以描述我想要使用结果集的目的。谢谢。

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


【解决方案1】:

我认为结合 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

结果:

【讨论】:

  • 做到了。我正要研究将数据拉入 C# 并在那里处理逻辑。极好的!谢谢。
【解决方案2】:
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

【讨论】:

  • 也感谢您,我将尝试两种解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 2019-06-26
  • 2017-09-28
  • 2016-07-04
  • 2010-10-21
相关资源
最近更新 更多