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

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
)

Related

ORA-01722: invalid number - getting this error

I am trying to execute below in oracle sql developer
select code, case when (code = 'SS') then 1 else to_number(code) end as code_modified
from pxrptuser.WBS
But I am getting error.
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
The output should be -
code code_modified
D0DV-IMS null
gWBS null
8 8
1 1
SS 1
Please help me with the actual query
You have strings in your data that cannot be converted to numbers (other than "SS").
Starting Oracle 12.2, you can use the on conversion error clause to to_number() to return null for invalid values:
select code,
case
when code = 'SS' then 1
else to_number(code default null on conversion error)
end as code_modified
from pxrptuser.WBS
In earlier versions, one alternative uses a regex. If your numbers have no decimal part, as showned in your data, it is simpler:
select code,
case
when code = 'SS' then 1
when not regexp_like(code, '\D') then to_number(code)
end as code_modified
from pxrptuser.WBS

how to use case with count function in oracle plsql

here is the query, i want to use case statement with count function in oracle.
Select case when count(*) > 0 then 'doSomething' else 'doSomething'
from student where student_name='faizan ahmed' and student_father='ahmed' and UPPER(student_dob)=UPPER('01-FEB-19');
please help me out, using plsql code.
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
For this purpose, use exists instead:
Select (case when exists (select 1
from student
where student_name = 'faizan ahmed' and
student_father = 'ahmed' and
upper(student_dob) = upper('01-FEB-19');
then 'doSomething'
else 'doSomethingElse'
end)
from dual;
EXISTS is usually more efficient than a count, because it can stop at the first matching row instead of aggregating the whole table.
You're missing an END for CASE:
SELECT CASE WHEN COUNT (*) > 0 THEN
'doSomething'
ELSE 'doSomething'
END --> This
FROM student
WHERE student_name = 'faizan ahmed'
AND student_father = 'ahmed'
AND UPPER (student_dob) = date '2019-02-01' -- No! UPPER ('01-FEB-19');
It is easier to spot if you format code you write.
Apart from that, STUDENT_DOB seems to be a date. If so, then don't compare it to a string (because '01-feb-19' IS a string) but to a date (date '2019-02-01' - it is a date literal, consists of the date keyword and yyyy-mm-dd value).
Also, it is strange that you used UPPER with that "date" string, but all your names are lowercase. Hm?

Complex SELECT IN doesn't work in Oracle 11

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.

Oracle Error when dividing by Zero

I have a query where I need to get a certain number divided by 2 fields in 2 columns.
shelve.total_qty/(GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7) as Shelve_DOC
I get the notorious error.
ORA-01476: divisor is equal to zero
01476. 00000 - "divisor is equal to zero"
*Cause:
*Action:
I have read around I need a CASE/IF but I'm not sure how to..
Any help would be appreciated.
SELECT
CASE WHEN (GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7) = 0 THEN null
ELSE shelve.total_qty/(GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7)
END Shelve_DOC
FROM ...
WHERE ....
Should do the trick.
Something like this?
CASE WHEN NVL(y.FORECAST_QUANTITY,0) <= 0 AND NVL(z.sales,0) <= 0
THEN NULL
ELSE shelve.total_qty/(GREATEST(NVL(y.FORECAST_QUANTITY, 0), NVL(z.sales, 0))/7)
END AS Shelve_DOC

Encountered "ORA-00907: missing right parenthesis" using insrt function in oracle SQL

I am trying to test this sql query but I always encounter an error stating missing right parenthesis at row 1. I am guessing it has something to do with the INSTR function because my query just works fine if I replace INSTR function with a column name.
* row 1
SELECT INSTR(diary.entry, 'service', 1, 1 > 0)
FROM diary journal
WHERE journal.req_time >= '00:00:00'
AND journal.req_time <= '00:10:59';
Anyone care to help? Thanks
I think it is
SELECT INSTR(diary.entry, 'service', 1, 1) > 0
INSTR Function
INSTR Function Example