Question

My table has 4 columns namely recordID, expAverage ( representing exponential average), totalVolume and calculationDate. I have written this Query in MySQL to get open, high, low and close group by hour and it is working very nicely. I am not sure if this is the best way to write this query but it is giving correct output for me. Now I need to change this query to Oracle. I tried similar approach in Oracle but query does not seem to be working. How can I convert this query to work in Oracle database?

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
Was it helpful?

Solution

There are better ways to do this in 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;

Note these changes:

  1. The use of trunc(CalculationDate . . .) rather then extracting each component.
  2. The removal of CalculationDate from the SELECT clause. This is an error in Oracle. Note: I think the "clean" hour is a better choice than an arbitrary value. But, you can put in MIN(calculationDate) to better emulate the MySQL code if you really want.
  3. The use of keep syntax rather than a subquery.

OTHER TIPS

My guess is that your functions YEAR, MONTH, DAY and HOUR are failing because they do not exist in ORACLE dialect of SQL.

I would suggest to use TRUNC function to cut your date to the previous hour:

SELECT
<output columns>
FROM calculation c1
GROUP BY trunc(calculationDate, 'HH24')
ORDER BY calculationDate ASC
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top