Sql query for 3 tables checks either of table - sql

I am having 3 tables
1 : Employee
2 : Department
3 : Experts
I want the experts which belong to CmpId = 1
Employee :
id CmpId
1 2
2 1
3 1
Department
id CmpId
1 1
2 2
3 2
Experts :
id EmployeeId DepartmentId
1 1 2
2 2 null
3 null 1
4 2 1
5 null null

Let me guess that NULL in the expert table means that someone is an expert for all departments. If so:
select e.employeeid
from experts e join
departments d
on e.departmentid = d.id or e.departmentid is null;

If I understand the question correctly, the desired results based on the sample data should be Expert ID's 2,3 and 4.
Expert ID 2 has an Employee ID of 2, which has a CmpID of 1.
Expert ID 3 has a Department ID of 1, which has a CmpID of 1.
Expert ID 4 has an Employee ID of 2, which has a CmpID of 1 and a Department ID of 1 which has a CmpID of 1.
If this is in fact the desired result set, I would write the following query.
SELECT ex.id, ex.EmployeeID, ex.DepartmentID
FROM #Experts ex
LEFT JOIN #Department dep
ON ex.DepartmentID = dep.id
LEFT JOIN #Employee emp
ON ex.EmployeeID = emp.id
WHERE dep.CmpID = 1 OR emp.CmpID = 1
That will yield the following results.
id EmployeeID DepartmentID
2 2 NULL
3 NULL 1
4 2 1

INNER JOIN the three tables
If they need to be CmpId = 1 in BOTH (this returns nothing in your sample data but assuming it is a larger data set)
SELECT e.id, e.EmployeeId, e.DepartmentId
FROM Experts e
FULL OUTER JOIN Department d ON e.DepartmentId = d.id
FULL OUTER JOIN Employee em ON e.EmployeeId = em.id
WHERE d.CmpId = 1 AND em.CmpId = 1
If they need to be CmpId = 1 in Either
SELECT e.id, e.EmployeeId, e.DepartmentId
FROM Experts e
FULL OUTER JOIN Department d ON e.DepartmentId = d.id
FULL OUTER JOIN Employee em ON e.EmployeeId = em.id
WHERE d.CmpId = 1 OR em.CmpId = 1

Related

How to write insert function or query

I have three tables which are very extensive, but I will give only a small version:
employee_position :
ID
position
1
Programmer
2
Administrator
3
Analyst
employee:
ID
name
1
Adam Smith
2
Sam Jones
3
Barbra Streisand
4
Dorothy Brown
employee_functions:
ID
employee_id
employee_position
1
1
3
2
3
1
Assuming what I need: if there is no employee in the employee_functions table [from the employee table] with an assigned position, then all positions in the employee_positions table should be assigned to him in this table.
I admit that I am not very fluent in SQL, so I would ask for help, can it be done with one query or can I do some function?
The final result for the given data (employee_functions):
ID
employee_id
employee_position
1
1
3
2
3
1
3
2
1
4
2
2
5
2
3
6
4
1
7
4
2
8
4
3
here is one way :
select employee_id ,employee_position from employee_functions f
union all
select e.id, p.id from employees e
cross join employee_position p
where e.id not in (select employee_id from employee_functions)
You can use insert . . . select, filtering out the employees who already have functions:
insert into employee_functions (employee_id, position_id)
select e.id, p.id
from employee e cross join
employee_positions ep
where not exists (select 1
from employee_functions ef
where ef.employee_id = e.id
);
insert into employee_functions (employee_id, position_id)
select e.id, p.id
from employee e cross join
employee_positions ep
where not exists (select 1
from employee_functions ef
where ef.employee_id = e.id
);

I have 2 different table like user and user_managers,i need to get manager details based on userid

user table
empId FirstName
1 a
2 b
3 c
4 d
5 e
usermanager table
empId ManagerId
1 2
2 null
3 4
4 5
5 3
result
empid managerid firstname
1 2 b
2 null null
3 4 d
4 5 e
5 3 c
If you also want to see users which doesn't have manager you should use LEFT JOIN. If you want to see only the users that have manager previous answers should work for you.
Here is a sample :
SELECT U.empId
, UM.ManagerId
, U.FirstName
FROM User U
LEFT JOIN UserManager UM ON U.empId = UM.empId
You can use just a LEFT JOIN statement with JOIN Condition u.empID = m.ManagerId
select m.empID, m.managerID, u.FirstName
from usermanager m
left join user u on u.empID = m.ManagerId;
Demo
it's just a join
select (columns that you want)
from user u, user_manager um
where u.empId = um.empId

SQL: Retrieve all records where has all joined

Sorry, couldn't think of a better title.
I have 3 tables in Oracle XE. An EMPLOYEE table a PROJECT table and a WORK_ON table. An EMPLOYEE can WORK_ON many PROJECTs. I am trying to get the employee name who is working on all the projects.
EMPLOYEE Table
Emp_ID EMP_Name
1 Esther
2 Peter
3 Joan
4 Roger
5 Liam
PROJECT Table
Project_ID
1
2
3
WROKS_ON Table
Emp_ID Project_ID
1 3
2 1
2 2
2 3
3 1
3 2
4 1
4 2
4 3
Given the fields my result should be Peter and Roger.
Started with the following, but got stuck:
SELECT EMP_NameLOYEE.E_NAME
FROM EMP_NameLOYEE INNER JOIN
(PROJECT INNER JOIN WROKS_ON ON PROJECT.Project_ID = WROKS_ON.Project_ID) ON
EMP_NameLOYEE.Emp_ID = WROKS_ON.Emp_ID
WHERE WROKS_ON.Project_ID In (SELECT DISTINCT Project_ID FROM PROJECT);
Obviously this retrieves all the names of the employees that are working on each project duplicated, but not exactly what I want.
You can leave the project table out of it.
SELECT e.emp_id, COUNT(project_id)
FROM employee e
INNER JOIN works_on wo ON wo.emp_id = e.emp_id
GROUP BY e.emp_id
HAVING COUNT( project_id ) = (SELECT COUNT(*) FROM project);
SQL Fiddle
You need to generate all combinations of employees and projects with a cross join and left join the works table and check for row counts for each e_name.
SELECT e.E_NAME
FROM EMPLOYEE e
CROSS JOIN PROJECT p
LEFT JOIN WORKS_ON w ON p.Project_ID = w.Project_ID and e.emp_id=w.emp_id
GROUP by e.E_NAME
HAVING COUNT(*)=COUNT(w.project_id)

how to display records which is present in employee but not present in department table

i want to get records which is present in employees table but not in department
i.e (Employees - department)
output should be like this
Employee(ID,Name), Department(Id,Name)
i tried this
select * from Employee as e
left join Department as d on e.DeptId = d.ID
sample data
ID Name DeptId Salary ID Name
1 krishna 1 5000 1 developer
2 rakesh 2 8000 2 trainer
3 sanjay 3 9000 3 programmer
4 swapna 4 6000 4 seo
6 shiva 6 4000 NULL NULL
i want to show records of shiva because he is in table employee but not in department table in sql server
Either use an OUTER JOIN as you've already done and filter by d.ID is null(as Dave has already shown). Or use NOT EXISTS which is my favorite:
select e.*
from Employee e
where not exists
(
select 1 from Department d
where e.DeptId = d.ID
)
Pros and cons of all approaches:
Should I use NOT IN, OUTER APPLY, LEFT OUTER JOIN, EXCEPT, or NOT EXISTS?
I had a little difficulty understanding the question but with your existing query a WHERE clause could be used to only show records that don't have an appartment.
select * from Employee as e
left join Department as d on e.DeptId = d.ID
WHERE d.ID is null
Alternatively
select
*
from Employee as e
WHERE e.ID not in (SELECT d.ID FROM Department d)

SQL Server matching all rows from Table1 with all rows from Table2

someone please help me with this query,
i have 2 tables
Employee
EmployeeID LanguageID
1 1
1 2
1 3
2 1
2 3
3 1
3 2
4 1
4 2
4 3
Task
TaskID LanguageID LangaugeRequired
1 1 1
1 2 0
2 1 1
2 2 1
2 3 1
3 2 0
3 3 1
LangaugeID is connected to table langauge (this table is for explaination only)
LangaugeID LanguageName
1 English
2 French
3 Italian
is there a possilbe way to make a query which gets employees where they can speak all the languages required for each task?
for example:
Task ID 1 requires only LanguageID = 1, so the result should be EmployeeID 1,2,3,4
Task ID 2 requires all 3 languages, so the result should be EmployeeID 1,4
Task ID 3 requires only LanguageID = 3, so the result should be EmployeeID 1,2,4
here is another variant to do this:
select t1.taskid, t2.employeeid from
(
select a.taskid, count(distinct a.languageid) as lang_cnt
from
task as a
where a.LangaugeRequired=1
group by a.taskid
) as t1
left outer join
(
select a.taskid, b.employeeid, count(distinct b.languageid) as lang_cnt
from
task as a
inner join
employee as b
on (a.LangaugeRequired=1 and a.languageid=b.languageid)
group by a.taskid, b.employeeid
) as t2
on (t1.taskid=t2.taskid and t1.lang_cnt=t2.lang_cnt)
###
here you can insert where statement, like:
where t1.taskid=1 and t2.employeeid=1
if such query returns row - this employee can work with this task, if no rows - no
###
order by t1.taskid, t2.employeeid
as you see, this query creates two temporary tables and then joins them.
first table (t1) calculates how many languages are required for each task
second table (t2) finds all employees who has at least 1 language required for task, groups by task/employee to find how many languages can be taken by this employee
the main query performs LEFT JOIN, as there can be situations when no employees can perform task
here is the output:
task employee
1 1
1 2
1 3
1 4
2 1
2 4
3 1
3 2
3 4
update: simpler, but less correct variant, because it will not return tasks without possible employees
select a.taskid, b.employeeid, count(distinct b.languageid) as lang_cnt
from
task as a
inner join
employee as b
on (a.LangaugeRequired=1 and a.languageid=b.languageid)
group by a.taskid, b.employeeid
having count(distinct b.languageid) = (select count(distinct c.languageid) from task as c where c.LangaugeRequired=1 and c.taskid=a.taskid)
Another version using NOT EXISTS
Retrieve all task-employee combinations where a missing language does not exist
SELECT t1.EmployeeId, t2.TaskId
FROM (
SELECT DISTINCT EmployeeID
FROM Employee
) t1 , (
SELECT DISTINCT TaskID
FROM Task
) t2
WHERE NOT EXISTS (
SELECT 1 FROM Task t
LEFT JOIN Employee e
ON e.EmployeeID = t1.EmployeeID
AND e.LanguageID = t.LanguageID
WHERE t.TaskID = t2.TaskID
AND LanguageRequired = 1
AND e.EmployeeID IS NULL
)
http://www.sqlfiddle.com/#!6/e3c78/1
You could use a Join logic to get the result, something like:
SELECT a.EmployeeID FROM Employee a, Task b WHERE b.LanguageRequired == a.LanguageID;