Oracle IN vs Exists difference? - sql

I am confused with oracle IN and EXISTS. I have below requirement.
I need to get all the employees whose names are in-
select * from emp where ename in('smith','brown','john','johnson');
Can i use EXISTS here? Also IN clause has 1000 limitation. Does EXISTS also has any such limitation?
Thanks!

simply put, EXISTS is usually used for checking whether rows that meet a criteria exist in another (or the same) table.
your SQL using EXISTS would look like this:
select *
from emp e
where exists(select * from emp e2 where e.empno = e2.empno and e2.ename in ('smith', 'brown', 'john', 'johnson'))
so you can see it's not what you need here

IN picks the list of matching values. EXISTS returns the boolean values like true or false. Exists is faster than in.
Example
IN
select ename from emp e where mgr in(select empno from emp where ename='KING');
EXISTS
select ename from emp e
where exists (select 1 from emp where e.mgr = empno and ename = 'KING');

Related

SQL Developer : Holding Multiple values in Variable From Query Result

I need help with query for sql developer.The requirement is a select statement which returns ID Column.I need to hold this ids in a variable and fetch the records associated with each id.Thanks for any help.
You can use join statement.
for example:
select id from table_1 join table_2
on table_1.id = table_2.id;
Not possible, as far as I can tell.
But, if it is the same query all over again and you use its result (those ID values you mentioned) in another queries, then you could create a view
create or replace view v_id as
select id
from some_table
where some_conditions;
and then use that view as yet another data source, e.g.
select d.dname, e.ename, e.job, e.sal
from emp e join v_id v on v.id = e.empno
join dept d on d.deptno = e.deptno;
or
select e.ename, e.job, e.sal
from emp e
where e.empno in (select v.id from v_id v);
or any other option you might choose.

finding a value in multi-values column

I have 2 tables as following:
Tam trying to get the department name of each employee (DepName column in table Emp table) from Dep table:
I have written this query:
update Emp
set DepName= (
select DepName
from Dep
where array_to_string(EmpID, ',') like EmpID
);
It did not update the table Emp with the requested information, although I haven't got any error. Any help?
You can do:
update emp
set dept = d.depname
from dep
where emp.empid = any (dep.empid);
Having pointed that out, you should not do this. Instead, I would suggest that you have a proper link to the department table and use join to bring in the department name.
you have to convert id int to character varying array data type and then use contains operator with table dept and update as usual
UPDATE emp t1
SET dept = dname
from dept t2
where t2.eid #> concat(concat('{',(t1.id::text)),'}') ::varchar[]
https://dbfiddle.uk/?rdbms=postgres_9.6&fiddle=e5c24b26b3479b68adf0b17c2050f715

How to get result in following scenario

I have table
EMP(id int primary key, name varchar2(15), mgrID int).
Now this table contain all employees(including worker and manager) in company. mgrID column contain id of employee to whom they are reporting.
I want to list the name of worker who is not manager along with their name of manager.
What to do for such query.
I tried nested select query as follows:
select name, (select name from EMP where mgerID is NULL)
as Manager from EMP;
Will this query give proper result?
You could use a self-join:
SELECT e.name AS name, m.name AS manager_name
FROM emp e
JOIN emp m ON e.mgrid = m.id
Your query should fail because you sub-query is uncorrelated and will return multiple results if you have multiple top-level managers.
select name
, (select name from EMP b where b.ID = a.mgerID ) as Manager
from EMP a;
I think the self-join is the more canonical solution, but you should understand the correlated subquery as well as it has many application.

How to change this db2 merge query?

can someone help me? i am trying to convert the following merge into another query and i am allowed only to use insert and update once:
MERGE INTO MYEMPLOYEE ME USING EMPLOYEE E ON ME.EMPNO = E.EMPNO
WHEN MATCHED THEN
UPDATE SET ME.SALARY = CASE WHEN ME.SALARY > E.SALARY THEN ME.SALARY ELSE E.SALARY END
WHEN NOT MATCHED THEN
INSERT VALUES(E.EMPNO, E.FIRSTNME, E.MIDINIT, E.LASTNAME, E.WORKDEPT, E.PHONENO, E.HIREDATE, E.JOB, E.EDLEVEL, E.SEX, E.BIRTHDATE, E.SALARY, E.BONUS, E.COMM);
How can I achieve this? the above merge copies the data if not exists, and if it exists it checks for the salary and selects the higher one and copies that one.
how can I achieve the same thing by only using one insert and one update? Can someone give me hints, please?
Thanks in advance :)
The purpose of the MERGE command is suppose to take into account multiple actions of UPDATE, INSERT, DELETE. MERGE statement explained
If you cannot/unable to use MERGE, then you have to resort to doing each request individually.
UPDATE MYEMPLOYEE ME
SET ME.SALARY = (
SELECT CASE WHEN ME.SALARY > E.SALARY THEN ME.SALARY ELSE E.SALARY END
FROM EMPLOYEE E
WHERE ME.EMPNO = E.EMPNO
)
WHERE EXISTS(
SELECT 1
FROM EMPLOYEE E
WHERE ME.EMPNO = E.EMPNO
);
Then do an insert where the employee don't exist in the master table.
INSERT INTO MYEMPLOYEE ME
SELECT *
FROM EMPLOYEE E
LEFT OUTER JOIN MYEMPLOEE ME ON E.EMPNO=ME.EMPNO
WHERE ME.EMPNO IS NULL;
If you need to do in one full sweep you can use the IMPORT command. But then you are dealing with files. You would need to export the EMPLOYEE table (probably with salary already formatted) and then import using the INSERT_REPLACE ability.
After trying I noticed that the INSERT code should actually be like this:
1) Don't use the Name ME twice
2) Select the necessary columns because after the join there are twice the column count
INSERT INTO MYEMPLOYEE (
SELECT E.EMPNO, E.FIRSTNME, E.MIDINIT, E.LASTNAME, E.WORKDEPT, E.PHONENO, E.HIREDATE, E.JOB, E.EDLEVEL, E.SEX, E.BIRTHDATE, E.SALARY, E.BONUS, E.COMM
FROM EMPLOYEE E LEFT OUTER JOIN MYEMPLOYEE ME ON E.EMPNO = ME.EMPNO WHERE ME.EMPNO IS NULL
);

SQL query how to print out manager name?

I need to create a query to display employee name and number along with their super's name and super number. Listing should also include employees who don't have any supervisor.
Select e.ename,e.empno,super.ename,super from emp e;
I don't know how to print out the manager/supervisor name, i just need that.
Join the table to itself using an outer join:
select e.ename, e.empno, super.ename, super.empno
from emp e
left join emp super on super.empno = e.super_empno
The left join will still return rows from emp that do not have a super defined.
EDIT
Due to OP's comment, here's how to do it without a join (using a nasty correlated sub-query):
select
ename,
empno,
(select super.ename from emp where empno = e.super_empno) as super_name,
super_empno
from emp e;