How can I use an alias inside a sub-query?
What I am trying to achieve is to get the rows having the maximum value from a table of the following form:
A | B | Ratio
0 | 1 | 1.0
1 | 2 | 1.0
2 | 3 | 1.0
3 | 4 | 0.33
4 | 5 | 0.25
I am trying to display only rows containing the maximum value (in this case 1.0). May be I am not doi开发者_如何学Cng this right. I have a query of the form:
SELECT A,B,C
FROM (---Long Sub Query--- Aliased as Full_Table)
WHERE RATIO=(SELECT MAX(RATIO) FROM Full_Table);
But Full_Table cannot be referenced from the second sub-query. There are some rows having the same maximum value which is the reason I was using this query. Is there a better construct to achieve this? In the worst case, I have to replace the second Full_Table by the entire long query but I'm hoping there is a better way to do this.
You can use a Common Table Expression:
WITH Full_Table AS (---Long Sub Query---)
SELECT A,B,C
FROM Full_Table
WHERE RATIO=(SELECT MAX(RATIO) FROM Full_Table);
Use:
SELECT full_table.a,
full_table.b,
full_table.c
FROM (SELECT ...,
RANK() OVER (ORDER BY ratio DESC) AS rank
FROM Sub Query---) full_table
WHERE full_table.rank = 1
It's not clear if there can be more than one record returned, so I used RANK()
rather than ROW_NUMBER()
because ROW_NUMBER
would only return one record.
You could incorporate that into a WITH
clause, but it's still one pass over the derived table/inline view vs your two passes...
Oracle 9i+ supports the WITH
syntax, calling it "Subquery Factoring". Those coming from SQL Server 2005+ know the WITH
syntax as a Common Table Expression (CTE). Unlike SQL Server's implementation, the WITH
syntax on Oracle 9i - 11g is not recursive - Oracle only added recursive WITH support (now that it's ANSI) in 11g R2, in part due to Oracle supporting recursive functionality with the CONNECT BY
syntax (supported since Oracle v2). WITH
syntax is syntactic sugar for derived tables/inline views - the query plan isn't reused for each instance.
WITH full_table AS (
SELECT...)
SELECT x.a, x.b, x.c
FROM full_table x
JOIN (SELECT MAX(t.ratio) AS max_ratio
FROM full_table t) y ON y.max_ratio = x.ratio
...is the identical to using:
SELECT x.a, x.b, x.c
FROM (SELECT ...) x
JOIN (SELECT MAX(t.ratio) AS max_ratio
FROM (SELECT ...) t) y ON y.max_ratio = x.ratio
精彩评论