Solved

pl/sql Order by within subquery

Posted on 2011-03-14
5
886 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

Question has a verified solution.

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

This post first appeared at Oracleinaction  (http://oracleinaction.com/undo-and-redo-in-oracle/)by Anju Garg (Myself). I  will demonstrate that undo for DML’s is stored both in undo tablespace and online redo logs. Then, we will analyze the reaso…
From implementing a password expiration date, to datatype conversions and file export options, these are some useful settings I've found in Jasper Server.
This video explains at a high level with the mandatory Oracle Memory processes are as well as touching on some of the more common optional ones.
This video shows, step by step, how to configure Oracle Heterogeneous Services via the Generic Gateway Agent in order to make a connection from an Oracle session and access a remote SQL Server database table.

707 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