I have an Orable database with a table like follows:
ID PROVIDER_ID FROM_CURRENCY TO_CURRENCY DATE AMOUNT ACTIVE
1 1 USD EUR 06-FEB-19 1.23 1
2 2 USD EUR 06-FEB-19 1.5 1
3 1 GBP EUR 06-FEB-19 1.23 1
4 1 CAD EUR 06-FEB-19 1.23 1
5 1 USD EUR 05-FEB-19 0.7 1
6 1 GBP EUR 05-FEB-19 0.7 1
As you can see, we store exchange rates from different providers with its date, and what I need is to get the IDs of the latest available rates for a specific to_currency
(eg. EUR) and provider_id
(eg. 1) at a certain date. So I should get something like follows:
ID
1
3
4
Please be aware that DATE is not unique so values can be duplicated among different rows and I can not use it to join with a subquery. Also, consider that DATE and ID are not correlated, so higher dates don't necessarily mean higher IDs (I cannot just use MAX(ID)
in the select clause to get the ID of the target row).
I have tried with the following query, but I get an error ORA-00979: not a GROUP BY expression
SELECT ID
FROM EXCHANGE_RATE
WHERE ACTIVE = 1 AND PROVIDER_ID = 1 AND TO_CURRENCY = 'EUR' AND DATE <= TO_DATE('2019-02-06', 'YYYY-MM-DD')
GROUP BY PROVIDER_ID, FROM_CURRENCY, TO_CURRENCY
HAVING DATE = MAX(DATE)
I've also tried the following query with the same error:
SELECT ID, MAX(DATE)
FROM EXCHANGE_RATE
WHERE ACTIVE = 1 AND PROVIDER_ID = 1 AND TO_CURRENCY = 'EUR' AND DATE <= TO_DATE('2019-02-06', 'YYYY-MM-DD')
GROUP BY PROVIDER_ID, FROM_CURRENCY, TO_CURRENCY
The query that retrieves the rows I need is the following one, but I don't know how to obtain the ID field for these rows since ID is not part of the group by clause.
SELECT MAX(DATE)
FROM EXCHANGE_RATE
WHERE ACTIVE = 1 AND PROVIDER_ID = 1 AND TO_CURRENCY = 'EUR' AND DATE <= TO_DATE('2019-02-06', 'YYYY-MM-DD')
GROUP BY PROVIDER_ID, FROM_CURRENCY, TO_CURRENCY
Any idea about how can achieve what I need?
EDIT I think I've found a solution
SELECT ID
FROM EXCHANGE_RATE E JOIN
(SELECT PROVIDER_ID, FROM_CURRENCY, TO_CURRENCY, MAX(DATE) AS LATEST
FROM EXCHANGE_RATE
WHERE DATE <= TO_DATE('2019-02-06', 'YYYY-MM-DD')
GROUP BY PROVIDER_ID, FROM_CURRENCY, TO_CURRENCY) LATEST_EX
ON E.PROVIDER_ID = LATEST_EX.PROVIDER_ID
AND E.TO_CURRENCY = LATEST_EX.TO_CURRENCY
AND E.FROM_CURRENCY = LATEST_EX.FROM_CURRENCY
AND E.DATE = LATEST_EX.LATEST
WHERE E.ACTIVE = 1 AND E.PROVIDER_ID = 1 AND E.TO_CURRENCY = 'EUR'
user row_number()
function to rank the dates in descending order for each currency
SELECT id
FROM
(SELECT id, provider_id, from_Currency,
row_number() over
( partition by from_Currency order by "DATE" desc ) as rn
FROM EXCHANGE_RATE
)
WHERE rn=1
The easiest way to write a stored proc to hold the data row returned by the final query and get the Id by fetching the pointer for that in the table.
SELECT MAX(DATE)
FROM EXCHANGE_RATE
WHERE ACTIVE = 1 AND PROVIDER_ID = 1 AND TO_CURRENCY = 'EUR' AND DATE <= TO_DATE('2019-02-06', 'YYYY-MM-DD')
GROUP BY PROVIDER_ID, FROM_CURRENCY, TO_CURRENCY
Apart from this, the only way to get the ID return from single query is to use that in group by but i dont see that will solve the purpose, the subquery will not work as well as mentioned by you.
Hope this helps :)
You can use a subquery
SELECT ID
FROM EXCHANGE_RATE
WHERE ("DATE") IN
(
SELECT MAX("DATE")
FROM EXCHANGE_RATE
WHERE ACTIVE = 1
AND PROVIDER_ID = 1
AND TO_CURRENCY = 'EUR'
)
AND ACTIVE = 1
AND PROVIDER_ID = 1
AND TO_CURRENCY = 'EUR'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.