我有一张包含产品,日期/时间和价格的表格。我将日期/时间拆分到另一列,我只是将其分成小时部分。我需要按小时找到价格值的高/低/开/关。通过在I 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
再次回顾一下,高/低很容易,因为我在选择部分中进行子选择,查询同一个表执行最大/最小值,但不确定如何执行相同的操作来打开/关闭以获取第一个和基于日期/时间字段的最后记录。
答案 0 :(得分:0)
将其添加为子查询以获取Open,适当地替换产品密钥和小时:
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>'
)
此路由的缺点是不保证这些语句返回单行。意味着对于给定产品,同一小时有两个条目,具有相同的Date值,即min / max,它将返回2行,当用作子查询时会导致异常。
虽然这可能是一件好事,但不是任意选择一行,您将知道存在特定问题并且可能更新查询以做出更明智的决定。
答案 1 :(得分: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