sqloracle-databasetop-ninline-view

How to fetch the top-n using inline view while performing a join with tables in main query in Oracle / SQL?


It seems like a really simple query but I must be missing something obvious. I am assuming that this scenario is pretty common.

I have a table which stores the products and another table that stores the transactions. The transaction table has information about the salesman. Now, I need to produce a report that lists all the products and includes id of the salesman who last sold this product.

I tried a simple query like:

select id, product_name, (select salesman_id from (select salesman_id from trans where product_id = a.id order by trans_date desc) where rownum = 1) salesman_id from products a

This query gave me invalid identifier on a.id.

so after searching the net, I tried to add a LATERAL clause to it. like follows

select id, product_name, salesman_id from products a, LATERAL(select salesman_id from (select salesman_id from trans where product_id = a.id order by trans_date desc) where rownum = 1)

but this query gives me incomplete SQL statement.

Is there a simple way to achieve this in a single query?


Solution

  • select id, product_name, salesman_id from
    (select p.id, p.product_name, t.salesman_id, row_number() over(partition by p.id order by t.trans_date desc) rw
      from products p left join trans t on t.product_id = p.id
    ) where rw = 1;
    
    1. Join tables products and trans
    2. Some products may not have transactions. As you need to show all products you need LEFT JOIN
    3. Use analytic functions to calculate order no (row_number) of each transaction for each product (order no begins from 1 for each product)