Сгруппируйте данные OHLC-Stockmarket на несколько таймфреймов с помощью T-SQL - PullRequest
3 голосов
/ 18 февраля 2012

Я использую SQL Server 2008 R2 и мне нужно создать новые таблицы, сгруппированные по временным интервалам.

Данные представляют собой данные из индекса фондового рынка. У меня есть данные с 1-минутными интервалами, теперь они мне нужны с 5,10,15,30,45,60 ... минутными интервалами. Мой первичный ключ - это отметка времени.

У меня вопрос: как запросить таблицу данных за 1 минуту, чтобы получить данные, сгруппированные по определенному интервалу времени, например, по 5 минутам.

Запрос должен возвращать значения «Самое высокое», «Самое низкое», «Последнее» и «Первое» в этой конкретной группе и, что наиболее важно, также последнюю запись метки времени в группе.

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

Данные:

TimeStamp          | Open | High | Low | Close
2012-02-17 15:15:0 | 102  | 110  |100  |105
2012-02-17 15:16:0 |106   |112   |105  |107
2012-02-17 15:17:0 | 106  |110   |98   |105
2012-02-17 15:18:0 |105   |109   |104  |106
2012-02-17 15:19:0 |107   |112   |107  |112
2012-02-17 15:20:0 |115   |125   |115  |124

Желаемый результат запроса (5 минут):

Timestamp       |Open|High|Low|Close
2012-02-15:19:0 |102 |125 |98 |124
2012-02-15:24:0 |115.|....|...|...
2012-02-15:29:0 |....|....|...|...

1 Ответ

3 голосов
/ 18 февраля 2012

Когда вы конвертируете datetime в float, вы получаете количество дней. Если вы умножите это на 24 * 12, вы получите 5-минутные интервалы. Так что если вы группируете по:

cast(cast(timestamp as float) * 24 * 12 as int)

Вы можете делать агрегаты за пять минут:

select  min(timestamp)
,       max(high) as Highest
,       min(low) as Lowest
from    @t
group by
        cast(cast(timestamp as float) * 24 * 12 as int)

Найти первый и последний ряд сложно в SQL Server. Вот один из способов использования row_number:

select  min(timestamp)
,       max(high) as Highest
,       min(low) as Lowest
,       min(case when rn_asc = 1 then [open] end) as first
,       min(case when rn_desc = 1 then [close] end) as Last
from    (
        select  row_number() over (
                    partition by cast(cast(timestamp as float) * 24 * 12 as int)
                    order by timestamp) as rn_asc
        ,       row_number() over (
                    partition by cast(cast(timestamp as float) * 24 * 12 as int)
                    order by timestamp desc) as rn_desc
        ,       *
        from    @t
        ) as SubQueryAlias
group by
        cast(cast(timestamp as float) * 24 * 12 as int)

Вот рабочий пример для SE Data.

...