Использование функций postgresql для возврата строк, чувствительных к дате

Я пишу функцию в postgresql для получения информации о свечах из набора имеющихся у меня данных о запасах. Чтобы нарисовать свечи, мне нужно получить значения открытия, закрытия, максимума и минимума определенного периода времени (скажем, 1 день), поэтому мне понадобится значение дня открытия, значение закрытия дня, самое высокое значение дня и минимальное значение дня.

Я создал функцию в postgresql, чтобы получить свечу на определенный период времени

CREATE OR REPLACE FUNCTION getcandle(
    starttime timestamp without time zone,
    endtime timestamp without time zone,
    psymbol character varying)
RETURNS candle AS
$BODY$
select
    startTime,
    (select value as open FROM "4" WHERE datetime >= startTime and symbol = pSymbol ORDER BY datetime ASC limit 1),
    (select value as close FROM "4" WHERE datetime <= endTime and symbol = pSymbol ORDER BY datetime DESC limit 1),
    (select max(value) as high FROM "4" WHERE datetime >= startTime and datetime <= endTime and symbol = pSymbol),
    (select min(value) as low FROM "4" WHERE datetime >= startTime and datetime <= endTime and symbol = pSymbol); $BODY$
LANGUAGE sql VOLATILE

И когда я запускаю это в течение определенного времени, я получаю что-то вроде этого:

select * from getCandle('2015-06-26 08:30:00', '2015-06-26 08:35:00', 'AAPL')
start                |open  |close |high  |low
---------------------|------|------|------|------
"2015-06-26 08:30:00"|127.51|127.32|127.51|127.23

Теперь я хочу написать еще одну функцию, которая выбирает все свечи определенного периода времени, я называю это getCandles, и вот что у меня так далеко от множества подобных поисковиков.

CREATE FUNCTION getCandles(startTime timestamp, endTime timestamp, pSymbol varchar, candleWidth int) RETURNS SETOF candle as $$
declare
    numberOfCandles int;
    candles candle%rowtype;
    localStart timeStamp;
    localEnd timeStamp;
begin
    numberOfCandles := (SELECT EXTRACT(EPOCH FROM (endTime - startTime))) / candleWidth;
    FOR i IN 1 .. numberOfCandles LOOP
        localStart := startTime + interval candleWidth * (i - 1) ' seconds';
        localEnd := startTime +  + interval candleWidth * i ' seconds';
        candles := getCandle(localStart, localEnd, pSymbol);
        return next candles;
    end loop;
return;
$$ language 'plpgsql';;

Моя самая большая проблема заключается в том, что когда я запускаю это, я получаю это:

ERROR:  syntax error at or near "*"
LINE 10:    localStart := startTime + interval candleWidth * (i - i) ...
                                                       ^

********** Error **********

ERROR: syntax error at or near "*"
SQL state: 42601
Character: 414

Итак, мои вопросы таковы:

1) Как использовать цикл for для увеличения моего таймфрейма на x секунд?

2) Правильно ли я добавляю строки в переменную моих свечей?

3) Есть ли лучший способ сделать что-либо из этого?

Кстати, я беру всю эту информацию и отображаю ее с помощью другой программы. Я бы предпочел не собирать всю информацию из почты и отправлять ее в свою программу, потому что я собираю почти 10 тысяч записей в день, поэтому, если бы я рассчитывал свечи в течение 7 дней или месяца, это был бы огромный запрос данных. Казалось, лучше написать набор функций, отсеивающих нужные мне данные. Огромное спасибо, Stack был удивительным ресурсом, и я не знаю, что бы я делал без него.

1 ответ

Я понял это, вот моя постоянная функция для тех из вас, кто столкнулся с этой же проблемой.

CREATE FUNCTION getCandles(startTime timestamp, endTime timestamp, pSymbol varchar, candleWidth int) RETURNS SETOF candle as $$
declare
    numberOfCandles int;
    candles candle%rowtype;
    localStart timeStamp;
    localEnd timeStamp;
begin
    numberOfCandles := (SELECT EXTRACT(EPOCH FROM (endTime - startTime))) / candleWidth;
    FOR i IN 1 .. numberOfCandles LOOP
        localStart := startTime + (candleWidth * (i - 1) * interval '1 second');
        localEnd := startTime + (candleWidth * i * interval '1 second');
        candles := getCandle(localStart, localEnd, pSymbol);
        return next candles;
    end loop;
return;
end
$$ language plpgsql;

Моей ошибкой было переключение интервала и ширины свечи.

Другие вопросы по тегам