Reputation: 451
Please have a look at the query.
The issue I am facing is this:
The FROM_LOCATION,TO_LOCATION in THEN clause needs to be the value from B_TARIFFS, However when I prefix it with B_TARIFFS.FROM_LOCATION
and B_TARIFFS.TO_LOCATION
, I get an error that ORA-00904: Invalid identifier.
.
If it is available in ELSE
clause then why cant I use it in the THEN
clause. What can I do to get my desired result.
The result I want from the query is this: Get from_location,to_location, tariff (based on case from another table). I am expecting that the Outer query will pass its FROM_LOCATION,TO_LOCATION to the inner select queries in CASE ELSE THEN
, and based on that a tariff value would be returned which will be the third column of the outer query. What can I do to achieve this.
select FROM_LOCATION, TO_LOCATION,
case when (
select tariff A_tariff where A_tariff.FROM_LOCATION = B_TARIFFS.FROM_LOCATION AND A_tariff.TO_LOCATION =
B_TARIFFS.TO_LOCATION AND TO_DATE(sysdate,'YYYY-MM-DD') between TO_DATE(from_date,'YYYY-MM-DD') and TO_DATE(to_date,'YYYY-MM-DD')
and rownum = 1
) = ''
then
(SELECT TARIFF FROM (
SELECT * FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(**FROM_LOCATION**) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(**TO_LOCATION**) ORDER BY A_TARIFF.FROM_DATE DESC
) WHERE ROWNUM = 1)
else
(select tariff from A_tariff where A_tariff.FROM_LOCATION = B_TARIFFS.FROM_LOCATION AND A_tariff.TO_LOCATION =
B_TARIFFS.TO_LOCATION AND TO_DATE(sysdate,'YYYY-MM-DD') between TO_DATE(from_date,'YYYY-MM-DD') and TO_DATE(to_date,'YYYY-MM-DD')
and rownum = 1) end tariff
FROM B_TARIFFS
WHERE FROM_LOCATION LIKE '%ABC%' AND AREA_CODE = 'X' ORDER BY TARIFFS;
Upvotes: 0
Views: 2827
Reputation: 14848
As mentioned by @alexandergs the cause of the error is too deep nesting of subquery. But you have bigger problems than that.
In your when
clause you make decision depending on some random row, because there is condition rownum=1
without ordering.
The same is in else
clause. Also it is not clear what this when (select ...) = ''
means - I suspect that you want to show something not empty,
but current construcion does not provide this. You have to rebuild your query to something like here:
select b.from_location, b.to_location, a.tariff, b.tariffs,
row_number() over (partition by b.from_location, b.to_location
order by a.from_date desc) rn
from b_tariffs b
left join a_tariff a
on a.from_location = b.from_location and a.to_location = b.to_location
and trunc(sysdate) between trunc(a.from_date) and trunc(a.to_date)
where b.from_location like '%ABC%' and b.area_code = 'X' order by b.tariffs;
... eventually add some more code for row_number() - so it sorts rows depending on your needs and take rows with RN = 1.
Upvotes: 1
Reputation: 192
Your problem is in the double nesting.
Why don't you change:
(SELECT TARIFF FROM (
SELECT * FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(**FROM_LOCATION**) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(**TO_LOCATION**) ORDER BY A_TARIFF.FROM_DATE DESC
) WHERE ROWNUM = 1)
with
SELECT TARIFF FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(B_TARIFFS.FROM_LOCATION) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(B_TARIFFS.TO_LOCATION) WHERE ROWNUM = 1
ORDER BY A_TARIFF.FROM_DATE DESC
Upvotes: 1