Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 892
  • Last Modified:

pl/sql Order by within subquery

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
mausy
Asked:
mausy
  • 4
1 Solution
 
sdstuberCommented:
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
 
sdstuberCommented:
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
 
sdstuberCommented:
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
 
sdstuberCommented:
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
 
mausyAuthor Commented:
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!

  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now