2014-01-08 5 views
1

У меня есть данные запаса, хранящиеся в течение 1 минуты, так что 1 строка = 1 минута, и я использую этот запрос, чтобы получить минимальную, максимальную сумму, первую и последнюю запись за каждый день.Совокупные данные за один день

У меня есть 511 1 минутных рядов на каждый день (с 0900 до 1730).

SELECT MAX(high), MIN(low), SUM(volume) from a2a where date = 20131202; 
SELECT open FROM a2a ORDER BY time LIMIT 1; 
SELECT close FROM a2a WHERE time = 1730 ORDER BY time DESC LIMIT 1; 

SELECT MAX(high), MIN(low), SUM(volume) from a2a where date = 20131203; 
SELECT open FROM a2a ORDER BY time LIMIT 1; 
SELECT close FROM a2a WHERE time = 1730 ORDER BY time DESC LIMIT 1; 

SELECT MAX(high), MIN(low), SUM(volume) from a2a where date = 20131204; 
SELECT open FROM a2a ORDER BY time LIMIT 1; 
SELECT close FROM a2a WHERE time = 1730 ORDER BY time DESC LIMIT 1; 

В Netbeans, это возвращает 9 вкладок:

Мои вопросы:

1) Есть ли способ, чтобы получить эти результаты в одной вкладке?

2) Нужно ли мне выполнять 3 разных варианта в день, или есть способ сделать это в одном запросе?

3) Есть ли более быстрый способ, чем это, для вычисления этих агрегатов? То, что опубликовано, так же, как пример, мне нужно получить сотни ежедневных данных.

Редактировать: Таблица a2a image. тип даты и времени CHAR, ope для закрытия DOUBLE, а том - INTEGER.

enter image description here

+0

Пожалуйста, дайте нам описание вашей таблицы a2a, включая типы данных ваших столбцов 'date' и' time'. –

ответ

1

Вы можете получить открытые и закрыть с помощью связанных подзапросов:

SELECT symbol, date, MAX(high) AS high, MIN(low) as low, SUM(volume) as volume, 
     (select open from a2a a2 where a1.symbol = a2.symbol and a1.date = a2.date order by time limit 1) as open, 
     (select close from a2a a2 where a1.symbol = a2.symbol and a1.date = a2.date order by time desc limit 1) as close 
    FROM a2a a1 
    GROUP BY symbol, date 
    ORDER BY symbol, date; 

Индекс по a2a(symbol, date, time) бы ускорить этот запрос.

+0

спасибо, используя ваш запрос с индексом, действительно супер-быстро! –

+0

1) как изменить этот запрос, если мне нужно будет агрегировать данные только для получения последних 100 ежедневных баров? Теперь он отлично работает, но он объединяет все данные, доступные в базе данных. И, 2) Как получить агрегированные данные за неделю или заполнить данные за 5 минут? –

+0

@Albertoacepsut. , , Вы должны задать другой вопрос, с этим ответом в качестве отправной точки. –

2

Попробуйте это за высокий/низкий/объем

SELECT symbol, 
     date, 
     MAX(high) AS dailyhigh, 
     MIN(low)  AS dailylow, 
     SUM(volume) AS dailyvolume 
    GROUP BY symbol, date 

Вы получаете одну строку в день на одного символа.

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

SELECT symbol, 
     date, 
     MIN(time) AS opentime 
    FROM a2a 
    GROUP BY symbol, date 

Теперь нам нужно найти начальную цену за эту метку времени. Как это сделать? Это сделано немного сложнее, потому что у вас может быть более одной строки для определенного времени и даты для этой проблемы.

SELECT a.symbol, 
     a.date, 
     AVG (a.open) AS dailyopen 
    FROM a2a a 
     JOIN (
     SELECT symbol, 
       date, 
       MIN(time) AS opentime 
      FROM a2a 
      GROUP BY symbol, date 
     ) AS b ON a.symbol = b.symbol 
       AND a.date = b.date 
       AND a.time = b.opentime 
    GROUP BY a.symbol, a.date 

Это выводит начальные записи (записи самого низкого времени) для каждого символа и даты.

Теперь мне кажется, что ваши закрывающие записи - это записи, имеющие временную метку 1730, или последнюю запись с временной меткой меньше 1730. Это превращается из мгновенного SQL в реальную работу, но это финансовые записи и Мэдофф находится в тюрьме, поэтому давайте сделаем все правильно. Вот время закрытия каждого символа на каждой дате.

SELECT symbol, 
     date, 
     MAX(time) AS closetime 
    FROM a2a 
    WHERE time <= 1730 
    GROUP BY symbol, date 

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

SELECT a.symbol, 
     a.date, 
     AVG (a.close) AS dailyclose 
    FROM a2a a 
     JOIN (
     SELECT symbol, 
       date, 
       MAX(time) AS closetime 
      FROM a2a 
      WHERE time <= 1730 
      GROUP BY symbol, date 
     ) AS b ON a.symbol = b.symbol 
       AND a.date = b.date 
       AND a.time = b.closetime 
    GROUP BY a.symbol, a.date 

Следующий шаг - объединить эти три сводных запроса вместе и ограничить диапазон дат, который вы обрабатываете.

SELECT d.symbol, d.date, d.dailyhigh, d.dailylow, d.dailyvolume, 
     o.dailyopen, 
     c.dailyclose 
    FROM (
     /* the first summary query, daily high low volume */ 
     ) AS d 
    JOIN (
     /* the second summary query, daily open */ 
     ) AS o ON d.symbol = o.symbol AND d.date = o.date 
    JOIN (
     /* the third summary query, daily close */ 
     ) AS c ON d.symbol = c.symbol AND d.date = c.date 
WHERE d.date >= DATE_FORMAT(NOW() - INTERVAL 3 DAY, '%Y%m%d') 
    AND d.date < DATE_FORMAT(NOW(), '%Y%m%d') 
ORDER BY d.symbol, d.date 

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

Это не просто, но он очень прост и ясен в отношении ваших бизнес-правил.

+0

Но вам нужно немного расширить его, чтобы получить первый и последний – Strawberry

+0

@Strawberry, немного? :-) Этот материал - настоящая работа. –

+0

@ Олли, большое спасибо, немного сложная для меня, но я буду внимательно изучать ее. –

Смежные вопросы