简体   繁体   中英

Oracle SQL Any comparision with subquery raises right paranthesis missing error

The query works fine with any operator for multiple values for any comparison.

SELECT Name, ID     
    from tblABC 
    where ID = ANY (1,2,3,4,5 )
        

But when a subquery is used for any comparison a right parenthesis missing error occurs

SELECT Name, ID     
    from tblABC 
    where ID = ANY (select ID from tblXYZ where ROWNUM <= 10 order by ID desc )
        

The subquery just gives the top 10 recent id entries from the selected table. Should there be a conversion to number or missing condition in this query?

The reason is order by , which is not necessary as it is evaluated after count stopkey (which is rownum < <constant> ).

 select * from table(dbms_xplan.display_cursor(format => 'BASIC +PREDICATE'));
\n|  PLAN_TABLE_OUTPUT | \n|  :----------------------------------------------------------------------- | \n|  EXPLAINED SQL STATEMENT: |\n|  ------------------------ | \n|  select /*+ gather_plan_statistics */ * from t where rownum < 5 order by | \n|  1 asc | \n|  | \n|  Plan hash value: 846588679 |\n|  | \n|  ------------------------------------ | \n|  |  Id | Operation | Name | | \n|  ------------------------------------ | \n|  |  0 |  SELECT STATEMENT | |  | \n|  |  1 |  SORT ORDER BY ||  | \n|  |* 2 |  COUNT STOPKEY | |  | \n|  |  3 |  TABLE ACCESS FULL| T |  | \n|  ------------------------------------ | \n|  | \n|  Predicate Information (identified by operation id): |\n|  --------------------------------------------------- | \n|  | \n|  2 - filter(ROWNUM<5) | \n|  | \n

If you are on Oracle 12C+, then you may use fetch first :

 select * from dual where 1 = any(select l from t order by 1 asc fetch first 4 rows only)
\n|  DUMMY |\n|  :---- | \n|  X | \n

Or row_number() for older versions:

 select * from dual where 1 = any ( select l from ( select l, row_number() over(order by l asc) as rn from t ) where rn < 5 )
\n|  DUMMY |\n|  :---- | \n|  X | \n

db<>fiddle here

It is order by part. It is not supported within sub-queries like this.

Just remove it. You don't need it for comparison anyway.

SELECT Name, ID     
  from tblABC 
where ID = ANY (select ID from tblXYZ where ROWNUM <= 10 )

You can use FETCH FIRST <n> ROWS ONLY instead of using the old ROWNUM in the subquery.

For example:

SELECT Name, ID     
from tblABC 
where ID = ANY (select ID 
                from tblXYZ 
                order by ID desc 
                fetch first 10 rows only)

See running example at db<>fiddle .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM