Solved

pl/sql Order by within subquery

Posted on 2011-03-14
5
882 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 74

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 74

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 74

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 74

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Working with Network Access Control Lists in Oracle 11g (part 2) Part 1: http://www.e-e.com/A_8429.html Previously, I introduced the basics of network ACL's including how to create, delete and modify entries to allow and deny access.  For many…
Shell script to create broker configuration file using current broker Configuration, solely for purpose of backup on Linux. Script may need to be modified depending on OS-installation. Please deploy and verify the script in a test environment.
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function
This video explains what a user managed backup is and shows how to take one, providing a couple of simple example scripts.

685 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