ORA-00907: missing right parenthesis
00907\. 00000 - "missing right parenthesis"
SELECT last_name
,salary
,DECODE(salary, salary < 6000, 0.36,
salary < 8000, 0.38,
salary < 10000, 0.4,
salary < 12000, 0.42,
salary < 14000, 0.44,
salary < 16000, 0.45) as "TAX RATE"
FROM employees;
Don't make your life a misery. Use CASE expression instead of DECODE.
select case when salary < 6000 then 0.36
when salary < 8000 then 0.38
...
when salary < 16000 then 0.45
else null
end as tax_rate
from employees
If you'd want to do it with DECODE, you'd use SIGN function (to check whether salary is less than certain amount), and then nest as many DECODEs as necessary. That works, but is a nightmare to maintain.
I don't have your table so I'll try to illustrate it using Scott's emp:
SQL> select ename, sal,
2 decode(sign(sal - 1000), -1, 'less than 1000',
3 decode(sign(sal - 1500), -1, 'less than 1500',
4 decode(sign(sal - 2000), -1, 'less than 2000'))
5 ) rate
6 from emp;
ENAME SAL RATE
---------- ---------- --------------
SMITH 840 less than 1000
ALLEN 1600 less than 2000
WARD 1250 less than 1500
JONES 2975
MARTIN 1250 less than 1500
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
<snip>
If you compare it to CASE, difference is more than obvious:
SQL> select ename, sal,
2 case when sal < 1000 then 'less than 1000'
3 when sal < 1500 then 'less than 1500'
4 when sal < 2000 then 'less than 2000'
5 end rate
6 from emp;
ENAME SAL RATE
---------- ---------- --------------
SMITH 840 less than 1000
ALLEN 1600 less than 2000
WARD 1250 less than 1500
JONES 2975
MARTIN 1250 less than 1500
<snip>
Related
I tried top % but that is not working in Oracle SQL. Offset and fetch next are working but I am not able to give percentage.
What will be the best way to fetch middle 80% rows?
Any help will be appreciated, thanks!
Middle 80%? That's between 10 and 90%, then? Let's suppose it is.
Sample data (Scott's EMP table), sorted by salary:
SQL> select ename, job, sal,
2 rank() over (order by sal) rnk
3 from emp order by sal;
ENAME JOB SAL RNK
---------- --------- ---------- ----------
SMITH CLERK 800 1
JAMES CLERK 950 2
ADAMS CLERK 1100 3
WARD SALESMAN 1250 4
MARTIN SALESMAN 1250 4
MILLER CLERK 1300 6
TURNER SALESMAN 1500 7
ALLEN SALESMAN 1600 8
CLARK MANAGER 2450 9
BLAKE MANAGER 2850 10
JONES MANAGER 2975 11
SCOTT ANALYST 3000 12
FORD ANALYST 3000 12
KING PRESIDENT 5000 14
14 rows selected.
CTE ranks employees by their salaries; the final where clause returns rows for those of them who fall into that "middle" 80% (the pct column).
SQL> with temp as
2 (select ename, job, sal,
3 rank() over (order by sal) rnk, -- rank rows by salary
4 count(*) over (order by null) cnt -- total number of rows
5 from emp
6 )
7 select t.*,
8 round(rnk / cnt * 100) pct -- percentage
9 from temp t
10 where round(rnk / cnt * 100) between 10 and 90;
ENAME JOB SAL RNK CNT PCT
---------- --------- ---------- ---------- ---------- ----------
JAMES CLERK 950 2 14 14
ADAMS CLERK 1100 3 14 21
WARD SALESMAN 1250 4 14 29
MARTIN SALESMAN 1250 4 14 29
MILLER CLERK 1300 6 14 43
TURNER SALESMAN 1500 7 14 50
ALLEN SALESMAN 1600 8 14 57
CLARK MANAGER 2450 9 14 64
BLAKE MANAGER 2850 10 14 71
JONES MANAGER 2975 11 14 79
SCOTT ANALYST 3000 12 14 86
FORD ANALYST 3000 12 14 86
12 rows selected.
SQL>
In Oracle SQL Developer I need to calculate some figures (count for instance) since first day till today monthly. How can I create a loop by changing month in a date field? Now I have a time range on WHERE clause like (date >= '2017-01-01' and date < '2019-01-01'). So what I need is a table that counts for months and inserts results in two columns: month (2019_01, 2019_02, etc) and count
Here's an example which might help you do what need. It is based on Scott's sample schema, its EMP table that contains the HIREDATE column which will be joined to a CTE named months; it utilizes hierarchical query to create "calendar" of 12 months (that's what the CONNECT BY clause does). It will have to be changed in your case, I presume.
Current data:
SQL> select empno, ename, hiredate
2 from emp
3 order by hiredate;
EMPNO ENAME HIREDATE
---------- ---------- ----------
7369 SMITH 17.12.1980
7499 ALLEN 20.02.1981
7521 WARD 22.02.1981
7566 JONES 02.04.1981
7698 BLAKE 01.05.1981
7782 CLARK 09.06.1981
7844 TURNER 08.09.1981
7654 MARTIN 28.09.1981
7839 KING 17.11.1981
7900 JAMES 03.12.1981
7902 FORD 03.12.1981
7934 MILLER 23.01.1982
7788 SCOTT 09.12.1982
7876 ADAMS 12.01.1983
14 rows selected.
SQL>
Query you might need:
SQL> with months as
2 (select add_months(date '1980-12-01', level - 1) mon
3 from dual
4 connect by level <= 12
5 )
6 select to_char(m.mon, 'mm.yyyy') mon,
7 count(e.empno)
8 from months m left join emp e on m.mon = trunc(e.hiredate, 'mm')
9 group by m.mon
10 order by m.mon;
MON COUNT(E.EMPNO)
------- --------------
12.1980 1 --> Smith
01.1981 0
02.1981 2 --> Allen, Ward
03.1981 0
04.1981 1 --> Jones
05.1981 1 --> Blake
06.1981 1 --> Clark
07.1981 0
08.1981 0
09.1981 2 --> Turner, Martin
10.1981 0
11.1981 1 --> King
12 rows selected.
SQL>
I try to get something in Oracle, if the commission is greater than 0.2 I would like to get 'GOOD', otherwise 'BAD'. And also if the commission is null I want to get 0. I know that is with NVL, but something get wrong with syntax. Can you help me?
SELECT LAST_NAME,
SALARY,
DECODE(
NVL(COMMISSION_PCT),
COMMISSION_PCT < 0,2, 'BAD', COMMISSION_PCT > 0,2, 'GOOD'
) CommissionResult
FROM EMPLOYEES;
First of all, 0.2 should be written as 0.2, not 0,2. But most importantly, decode is not suitable for this case.
In this case (and all other cases where you could use decode), you can use case, which is more flexible and a more verbose so it is easier to read too.
SELECT LAST_NAME,SALARY,
CASE WHEN NVL(COMMISSION_PCT) < 0.2 THEN
'BAD'
WHEN COMMISSION_PCT > 0.2 THEN
'GOOD'
END as CommissionResult
FROM EMPLOYEES;
In your this case, you will get NULL when the percentage is exactly 0.2. Maybe you just need an ELSE clause instead:
SELECT LAST_NAME,SALARY,
CASE WHEN NVL(COMMISSION_PCT) < 0.2 THEN
'BAD'
ELSE
'GOOD'
END as CommissionResult
FROM EMPLOYEES;
DECODE(
NVL(COMMISSION_PCT),
COMMISSION_PCT < 0,2,'BAD',COMMISSION_PCT > 0,2,'GOOD'
)
Your query is syntactically incorrect.
NVL syntax is incomplete
You have a typo in the decimal number, a comma instead of dot.
DECODE syntax doesn't support comparisons.
For your requirement, you could use CASE expression which is verbose and easy to interpret.
Using CASE
For example, using the standard EMP table in SCOTT schema:
SQL> SELECT ename,
2 sal,
3 CASE
4 WHEN NVL(comm, 0) < 0.2
5 THEN 'BAD'
6 WHEN NVL(comm, 0) > 0.2
7 THEN 'GOOD'
8 END CommissionResult
9 FROM emp;
ENAME SAL COMM
---------- ---------- ----
SMITH 800 BAD
ALLEN 1600 GOOD
WARD 1250 GOOD
JONES 2975 BAD
MARTIN 1250 GOOD
BLAKE 2850 BAD
CLARK 2450 BAD
SCOTT 3000 BAD
KING 5000 BAD
TURNER 1500 BAD
ADAMS 1100 BAD
JAMES 950 BAD
FORD 3000 BAD
MILLER 1300 BAD
14 rows selected.
However, if you must use DECODE, then you need to use SIGN to have the same functionality.
Using DECODE
SQL> SELECT ename,
2 sal,
3 DECODE( SIGN(NVL(comm, 0) - 0.2), -1, 'BAD', +1, 'GOOD') CommissionResult
4 FROM emp;
ENAME SAL COMM
---------- ---------- ----
SMITH 800 BAD
ALLEN 1600 GOOD
WARD 1250 GOOD
JONES 2975 BAD
MARTIN 1250 GOOD
BLAKE 2850 BAD
CLARK 2450 BAD
SCOTT 3000 BAD
KING 5000 BAD
TURNER 1500 BAD
ADAMS 1100 BAD
JAMES 950 BAD
FORD 3000 BAD
MILLER 1300 BAD
14 rows selected.
how can ı get this result with using employees table?for salary< average 0
for salary >avg 1
employee_id salary
a 1
b 1
c 0
d 0
e 0
f 1
You could simply calculate the AVERAGE of the salary and compare it with the SALARY for each employee in the CASE expression itself.
For example,
SQL> SELECT empno,
2 ename,
3 CASE
4 WHEN sal >
5 (SELECT AVG(sal) FROM emp
6 )
7 THEN 1
8 ELSE 0
9 END flag
10 FROM emp;
EMPNO ENAME FLAG
---------- ---------- ----------
7369 SMITH 0
7499 ALLEN 0
7521 WARD 0
7566 JONES 1
7654 MARTIN 0
7698 BLAKE 1
7782 CLARK 1
7788 SCOTT 1
7839 KING 1
7844 TURNER 0
7876 ADAMS 0
7900 JAMES 0
7902 FORD 1
7934 MILLER 0
14 rows selected.
SQL>
Alternate solution You could use AVG() analytic function.
For example,
SQL> SELECT empno,
2 ename,
3 CASE
4 WHEN sal > avg(sal) OVER(ORDER BY NULL) THEN
5 1
6 ELSE
7 0
8 END flag
9 FROM emp;
EMPNO ENAME FLAG
---------- ---------- ----------
7369 SMITH 0
7499 ALLEN 0
7521 WARD 0
7566 JONES 1
7654 MARTIN 0
7698 BLAKE 1
7782 CLARK 1
7788 SCOTT 1
7839 KING 1
7844 TURNER 0
7876 ADAMS 0
7900 JAMES 0
7902 FORD 1
7934 MILLER 0
14 rows selected.
SQL>
You could cross join on the average salary:
SELECT employee_id,
CASE WHEN salary > avg_salary THEN 1 ELSE 0 END AS salary
FROM employee
CROSS JOIN (SELECT AVG(salary)
FROM employee)
I have the table strucure as in the image.
I need to get the values added to the sum of previous values(shown in the REQUIRED RESULT)
I tried with the following query
SELECT empid,
sum(tot_hours) OVER (PARTITION BY empid ORDER BY empid ) AS tot_hours
FROM empDet
ORDER BY empid
But i get the following result set
But I need the result as in the first picture.
Can anyone help me doing this?
sum(tot_hours) OVER (PARTITION BY empid ORDER BY empid ) AS tot_hours
Your ORDER BY is incorrect. If you want the running SUM on the TOT_HOURS, then you should order by tot_hours.
For example, the below query will calculate the running sum of salary of employees in each department:
SQL> SELECT deptno,
2 sal,
3 SUM(sal) OVER (PARTITION BY deptno ORDER BY sal ) AS tot_sal
4 FROM emp
5 ORDER BY deptno;
DEPTNO SAL TOT_SAL
---------- ---------- ----------
10 1300 1300
10 2450 3750
10 5000 8750
20 800 800
20 1100 1900
20 2975 4875
20 3000 10875
20 3000 10875
30 950 950
30 1250 3450
30 1250 3450
30 1500 4950
30 1600 6550
30 2850 9400
14 rows selected.
SQL>
Update For duplicate values, the running total would be duplicate. To make it unique, use UNBOUNDED PRECEDING clause. For example,
SQL> SELECT empno, deptno,
2 sal,
3 SUM(sal) OVER (PARTITION BY deptno ORDER BY sal ROWS UNBOUNDED PRECEDING) AS tot_sal
4 FROM emp
5 ORDER BY deptno;
EMPNO DEPTNO SAL TOT_SAL
---------- ---------- ---------- ----------
7934 10 1300 1300
10 1300 2600
7782 10 2450 5050
7839 10 5000 10050
7369 20 800 800
7876 20 1100 1900
7566 20 2975 4875
7788 20 3000 7875
7902 20 3000 10875
7900 30 950 950
7521 30 1250 2200
7654 30 1250 3450
7844 30 1500 4950
7499 30 1600 6550
7698 30 2850 9400
15 rows selected.
SQL>