I am writing a query, which has nested queryies in select statement as below.
Select t1.R1,
(
select * from
(
select t2.R2
from table2 t2
where t2.Condition_1=t1.C1
order by t2.Condition_2 desc
)
where rownum=1
),
t1.R3
from table1 t1
I am trying to pass main queries object into a sub query inside a sub query in select statement.
When I execute this I am getting object invalid error at t1.C1
.
I am able to pass object of the main table table1
to the first sub query, but how can I pass the table1
column to sub query inside a sub query?
Can any please help me in this scenario?
You can nest this query inside of your main query by using a subquery. You can write a subquery in an expression or in a Structured Query Language (SQL) statement in SQL view.
A subquery is used to return data that will be used in the main query as a condition to further restrict the data to be retrieved. Subqueries can be used with the SELECT, INSERT, UPDATE, and DELETE statements along with the operators like =, <, >, >=, <=, IN, BETWEEN, etc.
An SQL subquery is a query within another query. They are used to run a query that depends on the results of another query. Subqueries let you do this without having to write two separate queries and copy-paste the results. Subqueries appear in a WHERE or HAVING clause.
The sub-query always executes before the execution of the main query. Subqueries are completed first. The result of the subquery is used as input for the outer query.
You can only refer to objects down to one level of subquery, so t1
just isn't recognised in the inner subquery.
There are a few ways to do this. Sticking with your current subquery, you can make that into an in-line view and join to that instead:
select t1.r1, t2.r2, t1.r3
from table1 t1
join (
select *
from (
select condition_1, r2
from table2
order by condition_2 desc
)
where rownum = 1
) t2 on t2.condition_1 = t1.c1;
The subquery finds one table2
record for each condition_1
, based on your ordering criteria; then that single row can be joined to a single row from table1
(assuming c1
is unique).
Or you could use an analytic function:
select r1, r2, r3
from (
select t1.r1, t2.r2, t1.r3,
row_number() over (partition by t2.condition_1
order by t2.condition_2 desc) as rn
from table1 t1
join table2 t2 on t2.condition_1 = t1.c1
)
where rn = 1;
This joins the two tables and then decides which of the table2
values to retain by looking at the already-joined result set, based on the ordering condition in the analytic function's windowing clause. The inner query run on its own would produce what you saw when you tried to join before, with all the 'duplicates' (not really duplicates in the result set, but multiple rows for each r1
/r3
pair from table1
), with an addition rn
column that ranks those result set rows within those duplicates; the outer query then filters that to only shows the rows ranked first.
SQL Fiddle demo of both approaches.
If condition_2
isn't unique then you'd need to decide how to handle ties - if table2
could have two r2
values for the same condition_1
and condition_2
combination. You could look at a different analytic function in that case - rank
for example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With