2

再帰が必要だと思うクエリに取り組んでいます。この場合、ベースケースとその構造を完全に理解することはできません。株式市場のデータがあり、日付ごとの移動平均と、2つの移動平均の差の符号(およびcteごとのシンボルと期間の値)による行番号/パーティションを比較したいと思います。パーティションを決定するために、0と1の列を使用しています。標準パーティションでは、行のグループの値が0の場合、結果は1に切り替わり、次に0に戻り、0はすべて一緒にパーティション化されます。結果セットに必要なのは、0から1へ、またはその逆に変更するたびに新しいパーティションです。私は今持っているコードを追加し(2番目の列は返されません。これは、目的の出力を表示するために追加されます)、これまでにいくつかのサンプルデータを下に追加しました。

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

サンプル結果セット(2列目は私が探しているものです):

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. の everty パーティション内の行をランク付けします(Symbol, FastPeriod, SlowPeriod, ChgSign)(再び、 の降順でTradeDate)。

  3. 2 つのランキングの違いを見つけます。これは、最終的なパーティショニングの追加基準になります。

  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 に答える