什么是Oracle Query来计算常规数据集的Open,High,Low和Close?

时间:2014-04-18 17:19:39

标签: sql oracle group-by

我的表有4列,即recordID,expAverage(代表指数平均值),totalVolume和calculationDate。我已经在MySQL中编写了这个查询,以便按小时开启,高,低和关闭,并且它工作得非常好。我不确定这是否是编写此查询的最佳方式,但它为我提供了正确的输出。现在我需要将此查询更改为Oracle。我在Oracle中尝试过类似的方法,但查询似乎没有起作用。如何将此查询转换为在Oracle数据库中工作?

SELECT
    recordID,
    COUNT(c1.recordID) as totalRecords,
    MAX(c1.expAverage) AS high,
    MIN(c1.expAverage) AS low,
    (SELECT c2.expAverage FROM calculation c2 WHERE c2.recordID = MIN(c1.recordID)) AS open,
    (SELECT c2.expAverage FROM calculation c2 WHERE c2.recordID = MAX(c1.recordID)) AS close,
    SUM(totalVolume) as totalVolume,
    calculationDate
    FROM calculation c1
    GROUP BY YEAR(calculationDate), MONTH(calculationDate), DAY(calculationDate), HOUR(calculationDate) ORDER BY calculationDate ASC

2 个答案:

答案 0 :(得分:0)

在Oracle中有更好的方法可以做到这一点。

SELECT recordID,
       COUNT(c1.recordID) as totalRecords,
       MAX(c1.expAverage) AS high,
       MIN(c1.expAverage) AS low,
       MAX(c1.expAverage) KEEP (DENSE RANK FIRST ORDER BY recordId) as open,
       MAX(c1.expAverage) KEEP (DENSE RANK LAST ORDER BY recordId) as close,
       SUM(totalVolume) as totalVolume,
       trunc(calculationDate, 'YYYY-MM-DD HH') as calculationDate
FROM calculation c1
GROUP BY trunc(calculationDate, 'YYYY-MM-DD HH')
ORDER BY calculationDate ASC;

请注意以下更改:

  1. 使用trunc(CalculationDate . . .)而不是提取每个组件。
  2. CalculationDate子句中删除SELECT。这是Oracle中的错误。注意:我认为"清洁"小时是比任意值更好的选择。但是,如果你真的想要,你可以放入MIN(calculationDate)以更好地模拟MySQL代码。
  3. 使用keep语法而不是子查询。

答案 1 :(得分:0)

我的猜测是你的函数YEAR,MONTH,DAY和HOUR都失败了,因为它们不存在于SQL的ORACLE方言中。

我建议使用TRUNC功能将你的日期缩短到前一个小时:

SELECT
<output columns>
FROM calculation c1
GROUP BY trunc(calculationDate, 'HH24')
ORDER BY calculationDate ASC