Cannot use variable in select statement [duplicate] - sql

This question already has answers here:
How do I use variables in Oracle SQL Developer?
(10 answers)
Closed 2 years ago.
I need just use var as some value in Oracle SQL, something like this:
date = '21-Sep-10'
SELECT *
FROM (
SELECT *
FROM table2
WHERE some_date = date
) table1
WHERE table1.due_date = date;
How I can do this properly ?
Thanks !

It depends on tool you use. In SQL*Plus, you'd precede it with &
SELECT * FROM table WHERE id = &tmp;
In some other tools (SQL Developer, TOAD), that would be :
SELECT * FROM table WHERE id = :tmp;
If you're using the same variable more than once in the same query, precede it with two ampersands:
SQL> set linesize 200
SQL> set ver off
SQL> select *
2 from (select *
3 from emp
4 where deptno = &&deptno
5 )
6 where deptno = &&deptno;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09.06.81 2450 10
7839 KING PRESIDENT 17.11.81 5000 10
7934 MILLER CLERK 7782 23.01.82 1300 10
SQL>
However, if you run the same query once again, you won't be prompted for the variable (as it is "remembered"):
SQL> /
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09.06.81 2450 10
7839 KING PRESIDENT 17.11.81 5000 10
7934 MILLER CLERK 7782 23.01.82 1300 10
SQL>
You'll need to undefine it first:
SQL> undefine deptno
SQL> /
Enter value for deptno: 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17.12.80 800 20
7566 JONES MANAGER 7839 02.04.81 2975 20
7788 SCOTT ANALYST 7566 09.12.82 3000 20
7876 ADAMS CLERK 7788 12.01.83 1100 20
7902 FORD ANALYST 7566 03.12.81 3000 20
SQL>

Related

How can we handle multiple rows returned from a subquery inside a case statement?

Write a SELECT query if department id provided at run time is 100 then it will return all the employee details those belong to department 100 else i wanted to print all the employees from employee table.
i have written below query :-
SELECT * FROM EMPLOYEES
WHERE department_id IN (
CASE &InputDept
WHEN 100 THEN 100
ELSE (SELECT DISTINCT department_id FROM DEPARTMENTS) END ) ;
This works fine when input is 100 but returned "Single-row subquery returns more than one row".
i understand that case is a statement which works like "if-then-else" with single value, also i tried with decode but no luck.
This can be easily done in PL/SQL , but is this possible with SELECT query?
Skip the case expression, use regular AND/OR instead:
SELECT * FROM EMPLOYEES
WHERE (&InputDept = 100 and department_id = 100)
OR (&InputDept <> 100 and department_id IN
(SELECT department_id FROM DEPARTMENTS)) ;
To handle NULL InputDept:
SELECT * FROM EMPLOYEES
WHERE (&InputDept = 100 and department_id = 100)
OR ((&InputDept <> 100 or &InputDept IS NULL) AND department_id IN
(SELECT department_id FROM DEPARTMENTS)) ;
It's better to use a query like this:
SELECT * FROM EMPLOYEES
WHERE department_id = CASE &InputDept WHEN 100 THEN 100 END
UNION ALL
SELECT * FROM EMPLOYEES
WHERE (&InputDept != 100 or &InputDept is NULL)
AND department_id IN (SELECT DISTINCT department_id FROM DEPARTMENTS);
Do not forget about employees without department_id, ie NULLs.
This query will be optimized by optimizer at runtime to do not execute unneeded part of union all
Yet another alternative (example based on Scott's sample schema, ran in SQL*Plus):
SQL> select *
2 from emp
3 where deptno in (select deptno from dept
4 where &&inputdept <> 10
5 union all
6 select &&inputdept from dual
7 where &&inputdept = 10
8 );
Enter value for inputdept: 10
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09.06.81 2450 10
7839 KING PRESIDENT 17.11.81 5000 10
7934 MILLER CLERK 7782 23.01.82 1300 10
SQL> undefine inputdept
SQL> /
Enter value for inputdept: 25
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17.12.80 800 20
7499 ALLEN SALESMAN 7698 20.02.81 1600 300 30
7521 WARD SALESMAN 7698 22.02.81 1250 500 30
7566 JONES MANAGER 7839 02.04.81 2975 20
7654 MARTIN SALESMAN 7698 28.09.81 1250 1400 30
7698 BLAKE MANAGER 7839 01.05.81 2850 30
7782 CLARK MANAGER 7839 09.06.81 2450 10
7788 SCOTT ANALYST 7566 09.12.82 3000 20
7839 KING PRESIDENT 17.11.81 5000 10
7844 TURNER SALESMAN 7698 08.09.81 1500 0 30
7876 ADAMS CLERK 7788 12.01.83 1100 20
7900 JAMES CLERK 7698 03.12.81 950 30
7902 FORD ANALYST 7566 03.12.81 3000 20
7934 MILLER CLERK 7782 23.01.82 1300 10
14 rows selected.
SQL>

Can somebody please push me in right direction [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
My code below to delete duplicate entries
with mytable as
(
select a.*,
row_number() over(partition by emp_id order by emp_id) as Row_number
from employee_Details2 a
)
delete from mytable
where Row_number=2;
Error:
*ORA-00928: missing SELECT keyword
00928. 00000 - "missing SELECT keyword"
*Cause:
*Action:
Error at Line: 43 Column: 1*
You can't delete from a CTE.
If it is about deleting from employee_details2, then see if this helps:
delete from employee_details2 a
where a.rowid > (select min(b.rowid)
from employee_details2 b
where b.empid = a.empid
);
If you want to delete rows using "row number" (as you put it), well - yes, you can do that, but what I suggested originally is simpler and better.
SQL> select * From test order by deptno;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 06/09/1981 2450 10
7839 KING PRESIDENT 11/17/1981 10000 10
7934 MILLER CLERK 7782 01/23/1982 1300 10
7566 JONES MANAGER 7839 04/02/1981 2975 20
7902 FORD ANALYST 7566 12/03/1981 3000 20
7876 ADAMS CLERK 7788 01/12/1983 1300 20
7369 SMITH CLERK 7902 12/17/1980 920 20
7788 SCOTT ANALYST 7566 12/09/1982 3000 20
7521 WARD SALESMAN 7698 02/22/1981 1250 500 30
7844 TURNER SALESMAN 7698 09/08/1981 1500 0 30
7499 ALLEN SALESMAN 7698 02/20/1981 1600 300 30
7900 JAMES CLERK 7698 12/03/1981 950 30
7698 BLAKE MANAGER 7839 05/01/1981 2850 30
7654 MARTIN SALESMAN 7698 09/28/1981 1250 1400 30
14 rows selected.
SQL> delete from test b
2 where b.empno in (select c.empno
3 from (select a.empno, row_number() over (partition by a.deptno order by a.empno) rn
4 from test a
5 ) c
6 where c.rn > 1
7 );
11 rows deleted.
SQL> select * From test order by deptno;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 06/09/1981 2450 10
7369 SMITH CLERK 7902 12/17/1980 920 20
7499 ALLEN SALESMAN 7698 02/20/1981 1600 300 30
SQL>
The delete can not work with CTE, You need to separate the logic of DELETE and SELECT as follows:
delete from employee_Details2
where rowid in
(select rowid from
( select a.rowid, a.*,
row_number() over(partition by emp_id order by emp_id) as Row_number
from employee_Details2 a )
where Row_number = 2)

ORA-00913: too many values error when I run a query in SQL*Plus

I am trying to get the dname, loc, and count the ename's, plus I want to include the sal from the table. Can someone tell me what I am doing wrong.
Heres my statement with the error I get
SQL> select dname, loc, (select count(ename), sal from emp where DEPTNO = dept.deptno) as Number_of_people from dept;
select dname, loc, (select count(ename), sal from emp where DEPTNO = dept.deptno) as Number_of_people from dept
*
ERROR at line 1:
ORA-00913: too many values
SQL>
Heres my table
SQL> select empno, ename, job, hiredate, sal from emp;
EMPNO ENAME JOB HIREDATE SAL
---------- ---------- --------- --------- ----------
7839 KING PRESIDENT 17-NOV-81 5000
7698 BLAKE MANAGER 01-MAY-81 2850
7782 CLARK MANAGER 09-JUN-81 2450
7566 JONES MANAGER 02-APR-81 2975
7654 MARTIN SALESMAN 28-SEP-81 1250
7499 ALLEN SALESMAN 20-FEB-81 1600
7844 TURNER SALESMAN 08-SEP-81 1500
7900 JAMES CLERK 03-DEC-81 950
7521 WARD SALESMAN 22-FEB-81 1250
7902 FORD ANALYST 03-DEC-81 3000
7369 SMITH CLERK 17-DEC-80 800
EMPNO ENAME JOB HIREDATE SAL
---------- ---------- --------- --------- ----------
7788 SCOTT ANALYST 09-DEC-82 3000
7876 ADAMS CLERK 12-JAN-83 1100
7934 MILLER CLERK 23-JAN-82 1300
14 rows selected.
SQL>
Heres the second table
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
To get number of people and total Salary, try this...
select dept.dname, dept.loc,
count(emp.ename) as Number_of_people, sum(emp.sal) as Total_Salary
from emp
join dept on emp.DEPTNO = dept.deptno
group by dept.dname,dept.loc
You can get other things as well
select dept.dname, dept.loc,
count(emp.ename) as Number_of_people,
sum(emp.sal) as Total_Salary,
avg(emp.sal) as Average_salary,
min(emp.hiredate) as First_dept_hire,
max(emp.hireDate) as Last_dept_hire
from emp
join dept on emp.DEPTNO = dept.deptno
group by dept.dname,dept.loc
The scalar (inline) cursor can only have only one value in its projection.
If you want to have more than one value, use a join and aggregate all the values, as Sparky suggests.

I want to get all jobs that are in dept 30 including the location

I want to get all jobs that are in dept 30 including the location
SQL> select deptno,job from emp where deptno =30 (select loc from dept);
select deptno,job from emp where deptno =30 (select loc from dept)
*
ERROR at line 1:
ORA-00933: SQL command not properly ended
SQL>
Table emp
SQL> select empno, ename, job, hiredate, deptno from emp;
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- --------- ----------
7839 KING PRESIDENT 17-NOV-81 10
7698 BLAKE MANAGER 01-MAY-81 30
7782 CLARK MANAGER 09-JUN-81 10
7566 JONES MANAGER 02-APR-81 20
7654 MARTIN SALESMAN 28-SEP-81 30
7499 ALLEN SALESMAN 20-FEB-81 30
7844 TURNER SALESMAN 08-SEP-81 30
7900 JAMES CLERK 03-DEC-81 30
7521 WARD SALESMAN 22-FEB-81 30
7902 FORD ANALYST 03-DEC-81 20
7369 SMITH CLERK 17-DEC-80 20
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- --------- ----------
7788 SCOTT ANALYST 09-DEC-82 20
7876 ADAMS CLERK 12-JAN-83 20
7934 MILLER CLERK 23-JAN-82 10
14 rows selected.
Table dept
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
You need to join the two tables
SELECT deptno,
e.job,
d.loc
FROM emp e
JOIN dept d USING (deptno)
WHERE deptno = 30
SELECT empno, ename, job, hiredate, emp.deptno, location FROM emp
LEFT JOIN dept ON emp.deptno = dept.deptno
WHERE emp.deptno = 30

Getting data from two tables?

I am trying to get data from two different table and put into on statement but its not working. This is what I am looking to get as a complete statement: I want the query to display the dname, loc, Number of People. I am having a problems with the sub query.
SQL> select dname, loc from dept where ename in (count(ename) AS Number_of_People from emp);
select dname, loc from dept where ename in (count(ename) AS Number_of_People from emp)
*
ERROR at line 1:
ORA-00934: group function is not allowed here
SQL>
Table emp
SQL> select empno, ename, job, hiredate, deptno from emp;
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- --------- ----------
7839 KING PRESIDENT 17-NOV-81 10
7698 BLAKE MANAGER 01-MAY-81 30
7782 CLARK MANAGER 09-JUN-81 10
7566 JONES MANAGER 02-APR-81 20
7654 MARTIN SALESMAN 28-SEP-81 30
7499 ALLEN SALESMAN 20-FEB-81 30
7844 TURNER SALESMAN 08-SEP-81 30
7900 JAMES CLERK 03-DEC-81 30
7521 WARD SALESMAN 22-FEB-81 30
7902 FORD ANALYST 03-DEC-81 20
7369 SMITH CLERK 17-DEC-80 20
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- --------- ----------
7788 SCOTT ANALYST 09-DEC-82 20
7876 ADAMS CLERK 12-JAN-83 20
7934 MILLER CLERK 23-JAN-82 10
14 rows selected.
SQL>
Table dept
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
Are you trying to achieve something like this?
select dname, loc, (select count(ename) from emp where DEPTNO = dept.deptno) as Number_of_people
from dept;
I'm not sure what you're trying to do, but something that sticks out is that you probably need to use a select in your subquery. Try:
select dname, loc
from dept
where ename in (select count(ename) AS Number_of_People from emp);
Try this
select dept.dname, dept.loc,count(*)
from emp
join dept on emp.deptNo=dept.deptno
group by dept.dname,dept.loc