Complex SELECT IN doesn't work in Oracle 11 - sql

I have this query:
SELECT d.CREATION_DATE, r.RN5, s.rn1, s.PI1, r.KTR,
VERSION_NR, getTitle(r.RN5, VERSION_NR) AS TITLE
FROM DOI_SNAPSHOT d, RELATION r, SOURCE_ADDRESS s
WHERE r.RN1 NOT IN (8010,777)
AND d.RN5 = r.RN5
AND r.RN1 = s.RN1
AND r.RN5 IN (91010008,91010015)
AND r.RN5 not in (
SELECT RN5
FROM RELATION
WHERE DOI5 IS NOT NULL
AND DOI_DATE IS NULL
)
AND VERSION_NR = (
SELECT max(VERSION_NR)
FROM DOI_SNAPSHOT dmax
WHERE d.RN5 = dmax.RN5
);
and this query:
SELECT substr(w.message, 5, instr(w.message, 'KTR') - 5) AS RN5
FROM WEB_STATISTICS w
WHERE w.ACTION = 'DOI Display'
GROUP BY substr(w.message, 5, instr(w.message, 'KTR') - 5)
ORDER BY count(*) DESC;
both of them are working correctly.
Now if I replace the first query's line
AND r.RN5 IN (91010008, 91010015)
and put in the parenthesis the second query, I get an error
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
I don't know what is happening, since both queries are working oracle should at least accept the syntax?

The problem is that you have an order by clause in your second query, and you've left that in when you turned it into a subquery. The clause isn't valid in that context and makes no sense anyway - you're looking for members of a set, the ordering of the elements within that set is irrelevant - so you should remove the order by count(*) desc part.
To demonstrate with a simple but very contrived example; with an order by clause:
select * from dual
where dummy in (select 'X' from dual order by 1 desc);
SQL Error: ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
And without:
select * from dual
where dummy in (select 'X' from dual);
DUMMY
-----
X
As a simplistic explanation of the error message, when the parser see the order by it thinks that applies to the main query, and therefore the subquery should have already been terminated a closing right parenthesis - which is missing.
This is a message that often doesn't mean what you might think it implies - it isn't that the query overall has unbalanced parentheses, just that it's found a syntax error that may have been caused by a missing or misplaced one.

Generally error ORA-00907 usually means "there is a syntax error somewhere before this point".
Let's try
SQL> select * from dual
2 where dummy in (select dummy from dual);
DUMMY
-----
X
SQL> select * from dual
2 where dummy in (select dummy from dual order by 1);
ORA-00907: missing right parenthesis
So you should remove ORDER BY clause from inner query.

Related

Using COALESCE in oracle and getting ORA-00907: missing right parenthesis

I am trying to use COALESCE function in query but it throws an error ORA-00907: missing right parenthesis but the same query is running well in mysql i dont know how to write same query in orcale please help me out from this error.
SELECT DISTINCT sut.SERVICE_USER_TYPE , COUNT(er.ENFORCMENT_ID)
, SUM(er.FINE_AMOUNT),
COALESCE(er.CHECK_DATE>=('12-JAN-15'), er.CHECK_DATE<=('12-JAN-15''11.59.59.465000000 PM'))
from SERVICE_USER_TYPE sut
LEFT JOIN SERVICE_USERS su
ON su.SERVICE_USER_TYPE_ID = sut.SERVICE_USER_TYPE_ID
LEFT JOIN ENFORCEMENT_REPORT er ON su.SERVICE_USER_ID = er.SERVICE_USER_ID
group by sut.SERVICE_USER_TYPE ;
and the error
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Error at Line: 4 Column: 23
please help me out..
You say this works in MySQL. Well, the COALESCE expression results in 0, 1 or NULL per record. Then you aggregate your rows, but there is no aggregate on your COALESCE expression. This gives you a random 0, 1 or NULL per SERVICE_USER_TYPE.
The COALESCE expression
COALESCE(er.CHECK_DATE>=('12-JAN-15'), er.CHECK_DATE<=('12-JAN-15''11.59.59.465000000 PM'))
does the following in MySQL (only obfuscated):
CASE
WHEN er.CHECK_DATE IS NULL THEN NULL
WHEN er.CHECK_DATE >= '12-JAN-15' THEN 1
WHEN er.CHECK_DATE < '12-JAN-15' THEN 0
END
or, with NULL being the default, shortly
CASE
WHEN er.CHECK_DATE >= '12-JAN-15' THEN 1
WHEN er.CHECK_DATE < '12-JAN-15' THEN 0
END
You can do the same in Oracle and any other DBMS, but think about what aggregate you want to see. (If you expect it to be the same within all records for a SERVICE_USER_TYPE, use MIN or MAX or AVG, whichever you like best.)
For instance:
MIN
(
CASE
WHEN er.CHECK_DATE >= DATE'2015-01-12' THEN 1
WHEN er.CHECK_DATE < DATE'2015-01-12' THEN 0
END
)

missing parenthesis error

So I created the following code:
Select c_id, c_name
From bk_CustWithOrders
where to_char(order_date,'MM-YYYY')=prevMonth(sysdate '2014-11-27', 4)
INTERSECT
Select c_id, c_name
From bk_CustWithOrders
where to_char(order_date,'MM-YYYY')=prevMonth(sysdate '2014-11-27', 3)
INTERSECT
Select c_id, c_name
From bk_CustWithOrders
where to_char(order_date,'MM-YYYY')=prevMonth(sysdate '2014-11-27', 2);
and I get the following error message:
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Error at Line: 3 Column: 55
I've tried adding parenthesis but then I incur another error. Not sure what to do.
I dont know anyting about the function prevMonth.
But, What I noticed is there is no separator between sysdate and '2014-11-27'.
prevMonth(sysdate '2014-11-27', 2);
Use ',' between sysdate and '2014-11-27' and recheck:
prevMonth(sysdate, '2014-11-27', 2);
else you have to use any one of sysdate or '2014-11-27'
prevMonth(sysdate, 2);
prevMonth('2014-11-27', 2);
Line 3, column 55 is exactly at start of this part:
'2014-11-27', 4)
He's saying : I don't understand why you put a whitespace as separator.
sysdate '2014-11-27' is invalid.
If you only want to specify a date literal, it should be: date '2014-11-27'
sysdate is a function that returns the current date. If you just want to pass the current date to the function, then use only sysdate.

Oracle "Select Level from dual" does not work as expected with to_number result

Why does
select *
from (
SELECT LEVEL as VAL
FROM DUAL
CONNECT BY LEVEL <= 1000
ORDER BY LEVEL
) n
left outer join (select to_number(trim(alphanumeric_column)) as nr from my_table
where NOT regexp_like (trim(alphanumeric_column),'[^[:digit:]]')) d
on n.VAL = d.nr
where d.nr is null
and n.VAL >= 100
throw a ORA-01722 invalid number (reason is the last row, n.VAL), whereas the similar version with numeric columns im my_table works fine:
select *
from (
SELECT LEVEL as VAL
FROM DUAL
CONNECT BY LEVEL <= 1000
ORDER BY LEVEL
) n
left outer join (select numeric_column as nr from my_table) d
on n.VAL = d.nr
where d.nr is null
and n.VAL >= 100
given that numeric_column is of type number and alphanumeric_column of type nvarchar_2. Note that the upper example works fine without the numerical comparison (n.VAL >= 100).
Does anybody know?
This problem was driving me crazy. I narrowed the problem to a simpler query
SELECT *
FROM (SELECT TO_NUMBER(TRIM (alphanumeric_column)) AS nr
FROM my_table
WHERE NOT REGEXP_LIKE (TRIM (alphanumeric_column), '[^[:digit:]]')) d
WHERE d.nr > 1
With alphanumeric_colum values of ('100','200','XXXX'); Running the above statement gave the "invalid number" error. I then made a slight change to the query to use the CAST function instead of TO_NUMBER:
SELECT *
FROM (SELECT CAST (TRIM (alphanumeric_column) AS NUMBER) AS nr
FROM my_table
WHERE NOT REGEXP_LIKE (TRIM (alphanumeric_column), '[^[:digit:]]')) d
WHERE d.nr > 1
And this correctly returned - 100, 200. I would think that those functions would be similar in behavior. It almost appears as though oracle is trying to evaluate the d.nr > 1 constraint before the view is constructed, which makes no sense. If anyone can shed light on why this is happening, I would be grateful. See SQLFiddle example
UPDATE: I did some more digging, because I don't like not knowing why something just works. I ran EXPLAIN PLAN on both queries and got some interesting results.
For the query that failed, the predicate information looks like this:
1 - filter(TO_NUMBER(TRIM("ALPHANUMERIC_COLUMN"))>1 AND NOT
REGEXP_LIKE (TRIM("ALPHANUMERIC_COLUMN"),'[^[:digit:]]'))
You will notice that the TO_NUMBER function is called first in the AND condition, then
the regexp to exclude alpha values. I am thinking oracle maybe does a short-circuit evaluation with the AND condition, and since it is executing TO_NUMBER first, it fails.
However, when we use the CAST function, the evaluation order is swapped, and the
regexp exclusion is evaluated first. Since for the alpha values, it is false, then the
second part of the AND clause is not evaluated, and the query works.
1 - filter( NOT REGEXP_LIKE (TRIM("ALPHANUMERIC_COLUMN"),'[^[:digit:]
]') AND CAST(TRIM("ALPHANUMERIC_COLUMN") AS NUMBER)>1)
Oracle can be strange sometimes.
I believe when it comes to the Predicate (where) clause, Oracle can/will reorder the entire plan as it sees fit. So with regard to the predicate, it will short-circuit (as OldProgrammer noted) the evaluation however it wants, and you wont be able to guarantee the exact order it occurs.
In your current SQL, you are depending on the predicate to remove non numbers. One option would be to not use "WHERE NOT regexp_like ..." and instead use regexp_substr with coalesce. For example:
create table t_tab2
(
col varchar2(10)
);
create index t_tab2_idx on t_tab2(col);
insert into t_tab2
select level from dual
connect by level <= 100;
insert into t_tab2 values ('123ABC456');
commit;
-- select values > 95 (96->100 exclude non numbers)
select d.* from
(
select COALESCE(TO_NUMBER(REGEXP_SUBSTR(trim(col), '^\d+$')), 0) as nr
from t_tab2
) d
where d.nr > 95;
This should run without throwing invalid number error. Note that the coalesce will return the number 0 for any non numbers coming from the data, you may want to change that based on your needs and data.

Incorrect syntax near ',' SQL Server Error

I am having the following error on my SQL Server Query I don't know how to overcome it Because I tried my best Please help me getting out of it:
CREATE TABLE d3 as SELECT sessionnumber, sessioncount, LEFT(timespent, 1) , COUNT
as cnt
FROM clusters
GROUP BY 1, 2, 3
The following error is generated:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
Please help me! Thanks in advance
This is not SQL Server syntax. You want select into:
SELECT sessionnumber, sessioncount, LEFT(timespent, 1) as TimeSpentCode, COUNT(*) as cnt
into d3
FROM clusters
GROUP BY sessionnumber, sessioncount, LEFT(timespent, 1);
All the columns need to have names. So I added one for the third column.
And, group by does not accept positional indicators in SQL Server, so I replaced them with the appropriate expressions.
You have the word count instead of count(something).

Subquery in select statement syntax error

I am trying to run the below query and i keep getting the error:**ORA-01756: quoted string not properly terminated**
SELECT
InnerTable."Cycle ID",
(
SELECT REPLACE(SYS_CONNECT_BY_PATH(CF_ITEM_NAME,'//'),'//','/')
AS "Path1"
FROM CYCL_FOLD
START WITH CF_FATHER_ID = InnerTable."Cycle ID"
CONNECT BY PRIOR CF_ITEM_ID = CF_FATHER_ID
) as "path1",
InnerTable."CSR/RCQ Name",
TEST.TS_DESCRIPTION as "Test Case Description",
FROM
(-- few conditions here
) InnerTable INNER JOIN TEST ON InnerTable."Test Case ID" = TEST.TS_TEST_ID
Can any body tell me what is wrong with the syntax..Thanks so much..
This error means you have an odd number of single quotes.
The snippet you posted only contains balanced pairs of quotes - in the REPLACE(SYS_CONNECT_BY_PATH(CF_ITEM_NAME() chain. So the problem must lie in the excised part of your query:
-- few conditions here
Does the redaction include any string literals? If so check them.
This error is easy to spot with an IDE which supports SQL syntax highlighting.
" i don't find any error with the single or double quotes"
Me neither. Hmmm.
There is the possibility that the / is escaping the quote somehow. That will depend on you client settings. In SQL*Plus ESCAPE is off by default and besides the default escape character is \. So your statement would work on my set-up ...
SQL> sho escape
escape OFFSQL> select '//' from dual
2 /
'/
--
//
SQL> c.//./
1* select '/' from dual
SQL> r
1* select '/' from dual
'
-
/
SQL> set escape on
SQL> r
1* select '/' from dual
'
-
/
SQL>
... but check your client settings anyway.