4

open-high-low-close データを取得するために、PostgreSQL 8.4.2 サーバーのテーブルにクエリを実行しようとしています。テーブルと私の最初のクエリは以下のとおりです。

質問: 以下のクエリ例のように、サブクエリを使用せずに同じ結果を得る方法はありますか? おそらく FIRST_VALUE() または LAST_VALUE() ウィンドウメソッドを使用していますか?

-- FIRST ATTEMPT AT OHLC
SELECT
  contract_id
, TO_CHAR(ts, 'YYMMDDHH24MI')
, (SELECT price FROM fill minF WHERE minF.fill_id = MIN(f.fill_id)) AS open
, MAX(f.price) AS high
, MIN(f.price) AS low
, (SELECT price FROM fill maxF WHERE maxF.fill_id = MAX(f.fill_id)) AS close
FROM fill f
GROUP BY 1,2
ORDER BY 1,2;

-- SIMPLIFIED DDL
CREATE TABLE fill
(
    contract_id SEQUENCE PRIMARY KEY
,   ts          TIMESTAMP
,   price       NUMERIC(10,4)
);
4

4 に答える 4

3

あなたはあなたのものを分単位でグループ化しています。これらは通常、毎日行われるため、これは間違っていると思います。私が間違っていたら、元に戻さなければなりません。

SELECT DISTINCT contract_id, ts::date,
  min(price) OVER w,
  max(price) OVER w,
 first_value(price) OVER w, 
 last_value(price) OVER w
FROM fill
WINDOW w AS (PARTITION BY contract_id, ts::date ORDER BY ts)
ORDER BY 1,2
于 2010-03-29T23:53:56.750 に答える
3

1日未満の解像度を取得したいと思います。これはうまくいくようです。

SELECT
  contract_id
, the_minute
, open
, high
, low
, close
FROM 
(
  SELECT
    contract_id
  , TO_CHAR(ts, 'YYMMDDHH24MI') AS the_minute
  , MIN(price) OVER w            AS low
  , MAX(price) OVER w            AS high
  , LAST_VALUE(price) OVER w     AS open   -- Note the window is in reverse (first value comes last)
  , FIRST_VALUE(price) OVER w    AS close  -- Note the window is in reverse (last value comes first)
  , RANK() OVER w                AS the_rank
  FROM fill
  WINDOW w AS (PARTITION BY contract_id, TO_CHAR(ts, 'YYMMDDHH24MI') ORDER BY fill_id DESC)
) AS inr
WHERE the_rank = 1
ORDER BY 1, 2;

ありがとう、スコット。あなたの答えは、次の解決策にたどり着くのに役立ちました。

于 2010-03-30T13:03:17.867 に答える
0

これが私がそれを解決した方法です:

select FLOOR(MIN(ts) / :period) * :period                    as timestamp,
       SUBSTRING_INDEX(MIN(CONCAT(ts, '_', price)), '_', -1) as open,
       max(price)                                            as high,
       min(price)                                            as low,
       SUBSTRING_INDEX(MAX(CONCAT(ts, '_', price)), '_', -1) as close,
       sum(amount)                                           as volume
from uni_tx
where asset = :asset
  and ts between :startTime and :endTime
GROUP BY FLOOR(ts / :period)
order by timestamp
于 2021-03-01T16:26:30.940 に答える