2

我正在处理一个我认为需要递归的查询。在这种情况下,我不太清楚基本情况以及如何构建它。我有股票市场数据,我想比较按日期降序排列的移动平均线,并按两个移动平均线之间差异的符号比较行号/分区(以及根据 cte 的符号和周期值)。我使用一列 0 和 1 来帮助确定分区。对于标准分区,如果一组行的值为 0,则结​​果切换为 1,然后返回 0,所有 0 都被分区在一起。我在结果集中需要的是一个新的分区,用于从 0 到 1 的每个更改,反之亦然。我添加了我现在拥有的代码(不返回第二列,添加它是为了显示我想要的输出)和一些示例数据,我到目前为止在下面,

WITH allData AS
(
    SELECT t1.Symbol, t.TradingDate AS TradeDate, t1.Period AS FastPeriod, t2.Period AS SlowPeriod, 
    t1.Value AS FastValue, t2.Value AS SlowValue, (t1.Value - t2.Value) AS SlowFastDiff,
    CASE 
        WHEN (t1.Value - t2.Value) < 0 THEN 0
        ELSE 1
    END AS ChgSign
    FROM tblTradingDays t RIGHT JOIN tblDailySMA t1 ON t.TradingDate = t1.TradeDate JOIN tblDailySMA t2 ON 
        t1.Symbol = t2.Symbol AND t1.TradeDate = t2.TradeDate
    WHERE t1.Period < t2.Period AND t1.Symbol < 'AC'
)

SELECT DENSE_RANK() OVER (ORDER BY Symbol, FastPeriod, 
    SlowPeriod) AS RowNOuter, Symbol, TradeDate, FastPeriod, SlowPeriod, FastValue, SlowValue, 
    SlowFastDiff, ChgSign
FROM allData
ORDER BY Symbol, FastPeriod, SlowPeriod, TradeDate DESC, RowNInner

示例结果集(第二列是我所寻求的):

RowNOuter   RowNInner     Symbol    TradeDate   FastPeriod  SlowPeriod  FastValue   SlowValue   SlowFastDiff    ChgSign
1           1             A         5/11/2012   5           10          40.05       41.166      -1.116           0
1           2             A         5/10/2012   5           10          40.362      41.477      -1.115           0
1           3             A         5/9/2012    5           10          40.856      41.702      -0.846           0
1           1             A         5/8/2012    5           10          42.018      41.78       0.238            1
1           2             A         5/7/2012    5           10          42.282      41.821      0.461            1
1           1             A         5/6/2012    5           10          41.542      41.797      -0.255           0
1           2             A         5/5/2012    5           10          41.36       41.778      -0.418           0
4

1 回答 1

3

如果我没有遗漏任何东西,这可以在没有递归 CTE 的情况下解决。

思路如下:

  1. 按(我猜)(Symbol, FastPeriod, SlowPeriod)的降序排列每个分区中的行。TradeDate

  2. 对每个分区内的行进行排名(Symbol, FastPeriod, SlowPeriod, ChgSign)(同样,按 的降序排列TradeDate)。

  3. 找出两个排名之间的差异。这将是最终划分的附加标准。

  4. 现在您可以再次对行进行排名,将它们划分为(Symbol, FastPeriod, SlowPeriod, ChgSign, RankDiff).

以下是生成的查询可能的样子:

WITH allData AS
(
    SELECT
        t1.Symbol,
        TradeDate    = t.TradingDate,
        FastPeriod   = t1.Period,
        SlowPeriod   = t2.Period,
        FastValue    = t1.Value,
        SlowValue    = t2.Value,
        SlowFastDiff = (t1.Value - t2.Value),
        ChgSign      = CASE WHEN t1.Value < t2.Value THEN 0 ELSE 1 END
    FROM tblTradingDays t
        RIGHT JOIN tblDailySMA t1 ON t.TradingDate = t1.TradeDate
        INNER JOIN tblDailySMA t2 ON t1.Symbol     = t2.Symbol
                                 AND t1.TradeDate  = t2.TradeDate
    WHERE t1.Period < t2.Period
      AND t1.Symbol < 'AC'
)
,    partitioned AS (
    SELECT
        RowOuter = DENSE_RANK() OVER (ORDER BY Symbol, FastPeriod, SlowPeriod),
        RankDiff = ROW_NUMBER() OVER (
                       PARTITION BY Symbol, FastPeriod, SlowPeriod
                       ORDER BY TradeDate DESC
                   )
                 - ROW_NUMBER() OVER (
                       PARTITION BY Symbol, FastPeriod, SlowPeriod, ChgSign
                       ORDER BY TradeDate DESC
                   ),
        Symbol,
        TradeDate,
        FastPeriod,
        SlowPeriod,
        FastValue,
        SlowValue, 
        SlowFastDiff,
        ChgSign
    FROM allData
)
SELECT
    RowOuter,
    RowInner = ROW_NUMBER() OVER (
       PARTITION BY Symbol, FastPeriod, SlowPeriod, ChgSign, RankDiff
       ORDER BY TradeDate DESC
    ),
    Symbol,
    TradeDate,
    FastPeriod,
    SlowPeriod,
    FastValue,
    SlowValue, 
    SlowFastDiff,
    ChgSign
FROM partitioned
ORDER BY Symbol, FastPeriod, SlowPeriod, TradeDate DESC, RowNInner
于 2012-05-14T07:42:50.717 回答