postgresql:在使用function组时,请帮助计算Postgres中的增量值

发布于 2025-02-06 16:59:54 字数 1706 浏览 4 评论 0原文

我正在构建一个Stockmarket数据库。我有一个带时间戳,符号,价格和数量的桌子。该量是每天累积交易的累积交易。对于例如,

|         timestamp          | symbol |  price   | volume |
|----------------------------|--------|----------|--------|
| 2022-06-11 12:42:04.912+00 | SBIN   | 120.0000 |      5 |
| 2022-06-11 12:42:25.806+00 | SBIN   | 123.0000 |      6 |
| 2022-06-11 12:42:38.993+00 | SBIN   | 123.4500 |      8 |
| 2022-06-11 12:42:42.735+00 | SBIN   | 108.0000 |     12 |
| 2022-06-11 12:42:45.801+00 | SBIN   | 121.0000 |     14 |
| 2022-06-11 12:43:43.186+00 | SBIN   | 122.0000 |     16 |
| 2022-06-11 12:43:45.599+00 | SBIN   | 125.0000 |     17 |
| 2022-06-11 12:43:51.655+00 | SBIN   | 141.0000 |     20 |
| 2022-06-11 12:43:54.151+00 | SBIN   | 111.0000 |     24 |
| 2022-06-11 12:44:01.908+00 | SBIN   | 123.0000 |     27 |

我想查询获取OHLCV(打开高低关闭和音量)数据。我正在使用以下内容获取OHLC数据,但没有卷,并且我得到了适当的OHLC。请注意,我正在使用类似于date_trunc的时间尺度db时数函数

SELECT
time_bucket('1 minute', "timestamp") AS time,
symbol,
max(price) AS high,
first(price, timestamp) AS open,
last(price, timestamp) AS close,
min(price) AS low,
FROM candle_ticks
GROUP BY time, symbol
ORDER BY time DESC, symbol;

。要获取以下数据,

|          time          | symbol |   high   |   open   |  close   |   low    | volume |
|------------------------|--------|----------|----------|----------|----------|--------|
| 2022-06-11 12:44:00+00 | SBIN   | 123.0000 | 123.0000 | 123.0000 | 123.0000 |   14   |
| 2022-06-11 12:43:00+00 | SBIN   | 141.0000 | 122.0000 | 111.0000 | 111.0000 |   10   |
| 2022-06-11 12:42:00+00 | SBIN   | 123.4500 | 120.0000 | 121.0000 | 108.0000 |    3   |

SQL应该是什么样的?我试图使用滞后,但是滞后和集体购买效果不佳。

I am building a stockmarket database. I have one table with timestamp, symbol, price and volume. The volume is cumulative volume traded per day. for e.g.

|         timestamp          | symbol |  price   | volume |
|----------------------------|--------|----------|--------|
| 2022-06-11 12:42:04.912+00 | SBIN   | 120.0000 |      5 |
| 2022-06-11 12:42:25.806+00 | SBIN   | 123.0000 |      6 |
| 2022-06-11 12:42:38.993+00 | SBIN   | 123.4500 |      8 |
| 2022-06-11 12:42:42.735+00 | SBIN   | 108.0000 |     12 |
| 2022-06-11 12:42:45.801+00 | SBIN   | 121.0000 |     14 |
| 2022-06-11 12:43:43.186+00 | SBIN   | 122.0000 |     16 |
| 2022-06-11 12:43:45.599+00 | SBIN   | 125.0000 |     17 |
| 2022-06-11 12:43:51.655+00 | SBIN   | 141.0000 |     20 |
| 2022-06-11 12:43:54.151+00 | SBIN   | 111.0000 |     24 |
| 2022-06-11 12:44:01.908+00 | SBIN   | 123.0000 |     27 |

I want to query to get OHLCV (open high low close and volume) data. I am using the following to get OHLC data but not volume and i am getting proper OHLC. Note that i am using timescale db timebucket function similar to date_trunc

SELECT
time_bucket('1 minute', "timestamp") AS time,
symbol,
max(price) AS high,
first(price, timestamp) AS open,
last(price, timestamp) AS close,
min(price) AS low,
FROM candle_ticks
GROUP BY time, symbol
ORDER BY time DESC, symbol;

So for volume, I need to calculate the difference of max / last volume in the same time and max/last volume in the previous time frame. to get the following data

|          time          | symbol |   high   |   open   |  close   |   low    | volume |
|------------------------|--------|----------|----------|----------|----------|--------|
| 2022-06-11 12:44:00+00 | SBIN   | 123.0000 | 123.0000 | 123.0000 | 123.0000 |   14   |
| 2022-06-11 12:43:00+00 | SBIN   | 141.0000 | 122.0000 | 111.0000 | 111.0000 |   10   |
| 2022-06-11 12:42:00+00 | SBIN   | 123.4500 | 120.0000 | 121.0000 | 108.0000 |    3   |

What should be sql be like? I tried to use lag, but lag and group buy together is not playing well..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦毁影碎の 2025-02-13 16:59:54

如果将查询放入CTE,它会起作用吗?

with ivals as (
  SELECT time_bucket('1 minute', "timestamp") AS time,
         symbol,
         max(price) AS high,
         first(price, timestamp) AS open,
         last(price, timestamp) AS close,
         min(price) AS low,
         max(volume) AS close_volume
    FROM candle_ticks
   GROUP BY time, symbol
)
select i.*,
       close_volume - coalesce(
                        lag(close_volume) 
                          over (partition by symbol, time::date
                                    order by time),
                        0 
                      ) as time_volume
  from ivals i
;

Would it work if you put your query in a CTE?

with ivals as (
  SELECT time_bucket('1 minute', "timestamp") AS time,
         symbol,
         max(price) AS high,
         first(price, timestamp) AS open,
         last(price, timestamp) AS close,
         min(price) AS low,
         max(volume) AS close_volume
    FROM candle_ticks
   GROUP BY time, symbol
)
select i.*,
       close_volume - coalesce(
                        lag(close_volume) 
                          over (partition by symbol, time::date
                                    order by time),
                        0 
                      ) as time_volume
  from ivals i
;
反话 2025-02-13 16:59:54

类似于 Mike Organek的答案,您可以通过CTE收集数据,然后在您的主疑问中,从您的主疑问中,从您的主疑Time列获取time上一个存储桶的值。您可以使用该值
左JOIN在同一天内的前一个时间存储库的行:

WITH buckets as (

SELECT
  time_bucket('1 minute', "timestamp") AS time,
  symbol,
  max(price) AS high,
  first(price, timestamp) AS open,
  last(price, timestamp) AS close,
  min(price) AS low,
  max(volume) AS close_volume
FROM candle_ticks
GROUP BY time, symbol
ORDER BY time DESC, symbol
)

SELECT
  b.*,
  coalesce(b.close_volume - b2.close_volume,0) time_volume

FROM
  buckets b
  LEFT JOIN buckets b2 ON (b.time::date = b2.time::date and b.time - interval '1 minute' = b2.time)

此方法将避免timeScaledB在窗口功能上放置的限制。

Similar to Mike Organek's answer, you can collect the data into buckets via CTE and then in your main query, subtract a minute from the time column to get the time value for the previous bucket. You can use that value to
LEFT JOIN the row for the previous time bucket within the same day:

WITH buckets as (

SELECT
  time_bucket('1 minute', "timestamp") AS time,
  symbol,
  max(price) AS high,
  first(price, timestamp) AS open,
  last(price, timestamp) AS close,
  min(price) AS low,
  max(volume) AS close_volume
FROM candle_ticks
GROUP BY time, symbol
ORDER BY time DESC, symbol
)

SELECT
  b.*,
  coalesce(b.close_volume - b2.close_volume,0) time_volume

FROM
  buckets b
  LEFT JOIN buckets b2 ON (b.time::date = b2.time::date and b.time - interval '1 minute' = b2.time)

This method will avoid the restrictions that TimescaleDB places on window functions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文