Требуется рекурсивная помощь SQL Server cte - PullRequest
1 голос
/ 04 марта 2012

Я пытаюсь сгенерировать набор данных, и я думаю, что требуется рекурсия, но я не могу полностью приспособить многочисленные примеры, которые я нашел, для моих целей.Конечный результат, который я хочу, довольно просто описать.

Используются две таблицы: первая с торговыми ценами на акции с соответствующими полями TradeDate, Symbol и Clse (цена закрытия) и таблица с указанием торговых дней.Я хотел бы разделить данные о ценах по символам, упорядоченные по дате, но я бы хотел, чтобы нумерация разделов / строк нарушалась, если в таблице ценообразования отсутствует дата сделки, поскольку эти данные поступают из веб-службы, котораяиногда немного непредсказуемо.

Моей первой попыткой был достаточно простой запрос на выборку, в котором было предложение WHERE, которое называлось udf, которое я написал, чтобы проверить, существуют ли непрерывные данные для этой комбинации символ / дата.Он работал (он работал), и в ночь, когда я запускал его, через 7 часов он был почти через символы, начинающиеся с 'A'.

РЕДАКТИРОВАТЬ :
Этот мой пост иответ некоторое время назад Справка по запросу на выбор SQL-сервера для хранимой процедуры, необходимой в SO, была концептуально полезной, но мое текущее использование концепции требует немного большего (объединение таблиц, разбиение на разделы / нумерация строк и т. д.)

Если это поможет понять проблему, я хочу использовать то, что возвращается, чтобы вычислить различные агрегации на символ, комбинацию даты сделки, которая использует прошлые точки данных.Пример: скользящее среднее за 5 периодов цены закрытия для символа / даты сделки будет средним из пяти цен закрытия (clse), имеющих дату сделки <= дата, для которой рассчитывается.Поэтому, используя приведенные ниже примеры данных из первой таблицы, я хочу вернуть 9,02 для символа «А», 3 периода, дата сделки 1/3/12.Если данные для одного из вычислений отсутствуют, я хочу получить значение NULL. </p>

Этот набор результатов, который я хочу, был бы простым запросом выбора 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 ]

2 голосов
/ 04 марта 2012

Я думаю, что объединение 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 голос
/ 04 марта 2012
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
...