2

我有一张包含产品、日期/时间和价格的表格。我将日期/时间拆分到另一列,我刚刚拆分了小时部分。我需要按小时查找价格值的高点/低点/开盘价/收盘价。我可以通过在我 max()/min() 的选择部分中进行子选择并按产品和小时加入数据来轻松获得高/低。我现在需要打开/关闭,这将是每小时的第一条记录和每小时的最后一条记录。每小时的每条记录的高/低/开/关都应该相同。

示例结果。注意所有 7 小时记录的最高价是 55,这就是所有 7 小时记录中的最高价,最低价是 30,因为它是所有 7 小时记录中最低的,50 是开盘价,因为第一个价格(按日期/时间排序在 7:15)是 50。收盘价是按日期/时间排序的一小时内的最后一个价格,即 30。

Product, Date,            Hour, Price, High, Low, Open, Close
A,       11/12/2012 7:15, 7,    50,    55,   30,  50,   30
A,       11/12/2012 7:28, 7,    55,    55,   30,  50,   30
A,       11/12/2012 7:30, 7,    40,    55,   30,  50,   30
A,       11/12/2012 7:35, 7,    45,    55,   30,  50,   30
A,       11/12/2012 7:55, 7,    30,    55,   30,  50,   30

所以再次回顾一下,高/低很容易,因为我在选择部分中对同一个表进行最大/最小查询的子选择,但不确定如何为打开/关闭做同样的事情以获取第一条和最后一条记录在日期/时间字段。

4

2 回答 2

0

将此添加为子查询以获取打开,适当地替换产品密钥和小时:

SELECT * FROM (
  Select Open
  FROM <table name>
  WHERE product = '<product key>' 
    AND hour='<the hour>'
  ORDER BY Date
) WHERE rownum = 1

将此添加为子查询以获取关闭,适当地替换产品密钥和小时:

SELECT * FROM (
  Select Close
  FROM <table name>
  WHERE product = '<product key>' 
    AND hour='<the hour>' 
  ORDER BY Date desc
) WHERE rownum = 1

这里的技巧是正确设置结果排序并使用rownum = 1.


另外的选择:

SELECT Open
FROM <table name>
WHERE product = '<product key>' 
  AND hour='<the hour>' 
  AND Date = (
    SELECT min(Date) 
    FROM <table name> 
    WHERE product = '<product key>' 
    AND hour='<the hour>'
    ) 

SELECT Close
FROM <table name>
WHERE product = '<product key>' 
  AND hour='<the hour>' 
  AND Date = (
    SELECT max(Date) 
    FROM <table name> 
    WHERE product = '<product key>' 
    AND hour='<the hour>'
    ) 

这条路线的一个缺点是这些语句不能保证返回单行。这意味着如果对于给定的产品,在同一小时有两个条目,具有相同的日期值是最小值/最大值,它将返回 2 行,当用作子查询时会导致异常。

尽管这可能是一件好事,但与其随意选择一行,您会知道存在特定问题,并且可能会更新查询以做出更明智的决定。

于 2012-11-12T20:27:42.883 回答
0

我会为此使用排名函数:

select product, datestr, hour,
       max(case when seqnum_open = 1 then price end) as Open,
       max(case when seqnum_close = 1 then price end) as Close,
       max(price) as High,
       min(price) as Low
from (select t.*,
             row_number() over (partition by product, datestr, hour order by date) as seqnum_open,
             row_number() over (partition by product, datestr, hour order by date desc) as seqnum_close
      from (select t.*,
                   to_char(date, 'YYYY-MM-DD') as datestr
            from t
           ) t
     ) t
group by product, datestr, hour
于 2012-11-12T21:01:51.143 回答