1

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

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

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

EDIT:
Это сообщение мой и ответ некоторое время назад SQL server select query help for stored procedure needed на SO было полезно концептуально, но мое текущее использование концепции требует немного больше (таблица соединения, нумерация разделов/строка и т.д.)

Если это помогает понять проблему, я хочу использовать то, что возвращается, чтобы рассчитать различные скопления на символ, комбинацию торговых дат, которые используют прошлые точки данных. Пример: 5-секундная скользящая средняя цены закрытия для символа/даты торговли будет равна среднему из пяти ценовых цен закрытия (закрытие), которые имеют дату торговли < = дата, рассчитанная для. Поэтому, используя приведенные ниже данные из первой таблицы, я хочу вернуть 9.02 для символа «A», 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 гораздо более четко, если я смогу заставить его работать как можно раньше на моих собственных данных. Благодарю.

+1

Я не думаю, что рекурсивное CTE поможет здесь. То, что вам понадобится, - это функция «lag» windowing. Но SQL Server пока этого не поддерживает. –

+0

@a_horse_with_no_name Действительно?Возможно, у меня есть хорошее понимание рекурсивного cte, потому что я не вижу, как это будет работать в этом приложении. Я не слышал о задержке. Возможно, мне нужен курсор и более процедура процедурного кода. – StatsViaCsh

+0

'lag' - стандартная функция окон, позволяющая получить доступ к значениям столбцов предыдущих строк. –

ответ

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

+0

Это сделало. Я как раз собирался посмотреть, как вытащить данные на C# и обрабатывать там логику. Фантастика! Благодарю. – StatsViaCsh

+0

Добро пожаловать :) –

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 
+0

Благодаря вам, я буду экспериментировать с обоими решениями. – StatsViaCsh