Solved

pl/sql Order by within subquery

Posted on 2011-03-14
5
872 Views
Last Modified: 2012-05-11
Hi,

I have a subquery where I want to get the topmost record of that subquery. My query is similar to to following:

SELECT u.USER_ID, (SELECT ua.USER_ALIAS FROM USER_ALIAS ua WHERE ua.USER_ID=u.USER_ID WHERE ROWNUMBER=1 ORDER BY ua.USER_ALIAS_ID DESC)
FROM USERS u;

Open in new window


Now, I have been reading in various places that the order by within a subquery won't work but I cannot figure out how to achieve this otherwise. Are analytic functions such as RANK, PARTITION etc. any use in this situation? My understanding of them is limited .....

Any help much appreciated.

Regards,

Tomás

0
Comment
Question by:mausy
  • 4
5 Comments
 
LVL 73

Expert Comment

by:sdstuber
ID: 35127606
you must put the rownum filter in an scope than the order by.


Order by is applied to the result set, so , if you have the rownum and order by within the same scope you are restricting to an effectively random 1 row, then ordering that one row
0
 
LVL 73

Expert Comment

by:sdstuber
ID: 35127633
unfortunately you can't push an outer table reference into a doubly nested query.


that is...  this is what you want, but the "u.user_id" loses its meaning and is unknown (invalid identifier) when placed within 2 layers of subqueries

 (SELECT user_alias
          FROM (SELECT   ua.user_alias
                    FROM user_alias ua
                   WHERE ua.user_id = u.user_id
                ORDER BY ua.user_alias_id DESC)
         WHERE ROWNUM = 1)
0
 
LVL 73

Expert Comment

by:sdstuber
ID: 35127641
So, using analytics you could do something like this...


SELECT user_id, user_alias
  FROM (SELECT u.user_id,
               ua.user_alias,
               ROW_NUMBER() OVER (PARTITION BY u.user_id ORDER BY ua.user_alias_id DESC) rn
          FROM users u, user_alias ua
         WHERE ua.user_id = u.user_id)
 WHERE rn = 1;
0
 
LVL 73

Accepted Solution

by:
sdstuber earned 500 total points
ID: 35127659
You could use a subquery with an aggregate keep clause


the aggregate in this case isn't particularly important,  you could use MAX too
it's the KEEP clause that is doing the ordering and first row selection

SELECT u.user_id,
       (SELECT MIN(ua.user_alias) KEEP (DENSE_RANK FIRST ORDER BY user_alias_id DESC)
          FROM user_alias ua
         WHERE ua.user_id = u.user_id)
           user_alias
  FROM users u;
0
 
LVL 1

Author Closing Comment

by:mausy
ID: 35127707
Perfect. Thanks sdsuber!
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Join & Write a Comment

Subquery in Oracle: Sub queries are one of advance queries in oracle. Types of advance queries: •      Sub Queries •      Hierarchical Queries •      Set Operators Sub queries are know as the query called from another query or another subquery. It can …
Note: this article covers simple compression. Oracle introduced in version 11g release 2 a new feature called Advanced Compression which is not covered here. General principle of Oracle compression Oracle compression is a way of reducing the d…
This video shows how to copy a database user from one database to another user DBMS_METADATA.  It also shows how to copy a user's permissions and discusses password hash differences between Oracle 10g and 11g.
This video explains what a user managed backup is and shows how to take one, providing a couple of simple example scripts.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now