MySQL: Using Case statements - mysql

I have three tables called 'Employees', 'Managers', 'Supervisors'
Employees
ID Name
1 Bob
2 Alex
3 Joe
4 Melissa
5 Hannah
Managers
MID Name
1 Bob
3 Joe
Supervisor
SID Name
3 Joe
4 Melissa
I am trying to check whether if an employee is either a manager or a supervisor or both, and have a result table that looks like
ID Manager Supervisor
1 Manager NULL
2 NULL NULL
3 Manager Supervisor
4 NULL SUPERVISOR
5 NULL NULL
I want to try using a case statement in order to determine whether a fellow Employee ID is either a manager and/or a supervisor. But i'm not sure how to do this.
I know that I have to do something like
SELECT e.id /*how do i select the last 2 columns bc they are new?*/
FROM Employees e, Managers m, Supervisor s
CASE WHEN e.id = m.mid THEN 'manager' /*i don't think this is the correct format*/
CASE WHEN e.id = s.sid THEN 'supervisor'
....

You want to use left join. Follow a simple rule: do not use commas in the from clause. Always use explicit join syntax. Ignore anyone or anything that tells you otherwise. Such advice is very out-of-date.
select e.id,
(case when m.mid is not null then 'Manager' end) as Manager,
(case when s.sid is not null then 'Supervisor' end) as Supervisor
from employees e left join
managers m
on e.id = m.mid left join
supervisors s
on e.id = s.sid;
Also note that your tables are not properly normalized. Because managers and supervisors are employees, you should only have the name column in the employees table. It should not be repeated in the other tables, unless the same person could have different names when they take on the different roles.

Try this:
SELECT ID , (
SELECT MID AS Manager
FROM Managers WHERE MID = ID
LIMIT 1
) AS Manager, (
SELECT SID AS Supervisor
FROM Supervisors WHERE SID = ID
LIMIT 1
) AS Supervisors
FROM Employees
This will display your result as follows
ID Manager Supervisor
1 1 NULL
2 NULL NULL
3 3 3
4 NULL 4
5 NULL NULL

Related

Select records in Mysql if the other column is set to none

how can I get all the departments where is a ID is equal to manager column or if the manager is set to NULL it is equal to the supervisor.
table_department:
dept_id, dept_name, manager_id, supervisor_id
1 IT-admin 1 NULL
2 IT-hardware NULL 1
3 IT-system 4 1
4 Engineering 3 NULL
table_users:
user_id, username
1 username1
2 username2
3 username3
4 username4
5 username5
If in my condition the user is username1 and his id is 1, How to query and show IT-admin and IT-hardware department because username1 is the manager/supervisor of that departments.
Any help would be appreciated, Thank you.
Try this:
SELECT dept_id, dept_name, user_id, username
FROM table_department
INNER JOIN table_user ON COALESCE(manager_id, supervisor_id) = user_id;
I suggest aggregating by the coalesced value of the manager/supervisor ID value. Then, use conditional aggregation to pivot out the correct department. For users who are supervisors, choose the supervisor department, otherwise use the manager department.
SELECT COALESCE(manager_id, supervisor_id) AS user_id,
CASE WHEN COUNT(CASE WHEN supervisor_id IS NOT NULL THEN 1 END) > 0
THEN MAX(CASE WHEN supervisor_id IS NOT NULL THEN dept_name END)
ELSE MAX(CASE WHEN manager_id IS NOT NULL THEN dept_name END)
END AS dept_name
FROM table_department
GROUP BY 1;
Demo
By the way, it would probably help to better normalize your table design, and get a single column per user with possible role values. This would avoid the ugly CASE expressions in my answer.
You can either use OR in you query.
select * from table_department d
where exists (select 1 from table_users u
where u.username = 'username1'
and (u.id = d.manager_id or (d.manager_id is NULL and u.id = d.supervisor_id)))

Complex select statment using Mysql

I dont't now how to explain but i have two table in my database.
tab 1: service
tab 2: department
service table:
idService
serviceName
department_ID
is_deleted
department table:
departmentId
departmenetName
is_deleted
I want select all services with the departement name but with departement also if there is no service assigned to it.
if there is no service assigned to a departement then the flelds will be shown but i must have null or equivalent in idService field.
The result would be like this :
serviceID
serviceName
departmentId
departmenetName
1
IT
2
SI
2
Maintenance
6
Mechanical
3
Maintenance
6
Mechanical
4
Opt Manager
7
Finance
5
Instrument
5
Electric
NULL
NULL
1
Civil
8
Agro
NULL
NULL
_________
___________
____________
_______________
I have tried all kind of join options but I couldn't find the logic behind.
I use Mysql as DB
Any idea please ? Thank you.
you could try using an union between the left joined tables whit and without service
select a.serviceID, a.serviceNam, b.departmentId, b.departmenetName
from service a
left join department b on a.department_ID = b.departmentId
UNION
select null, null, b.departmentId, b.departmenetName
from department b
left join service a a.department_ID = b.departmentId
where a.serviceID is null

I am having 2 tables with 3 columns each and I want to get the value without null considering null may be present in any columns and rows

I want to get the output of 2 tables by removing the NULL
Emp Table
id name dept
1 Null EE
2 Ravi Null
NULL Mani CSE
Stud Table
id name dept
1 Manju NULL
2 NULL ECE
3 Mani CSE
Output
id name dept
1 Manju EE
2 Ravi ECE
3 Mani CSE
You can try below - using left join and coalesce() function
select a.id, coalesce(a.name,b.name) as name, coalesce(a.dept,b.dept)
from stud a left join emp b
on a.id=b.id
I don't know why your ID is nullable, from what I can see it is the primary key of you table. But if you want to select all data removing the NULL. Just add a condition.
For example:
SELECT COALESCE(e.name, s.name) name,
COALESCE(e.dept, s.dept) dept
FROM emp e
LEFT JOIN stud s
ON s.id = e.id
But honestly, you should check the way you created your database. As someone commented, this is not a relational table.

Compare two lists and return values not contained in the other list

Employee List (List 1)
USER ID NAME
1 John
2 Jane
3 Rob
4 Bill
5 Sally
Enrolled Students (List 1)
ID PID USER_ID
1 1 1
2 1 2
3 2 1
4 2 2
5 2 3
I am trying to find a way to determine if I want to look up who is not enrolled in x course.
So if I wanted to know which employees were not enrolled in Course 1 the result would be
USER_ID
3
4
5
Then if I wanted to know who is not enrolled in course 2
USER_ID
4
5
I tried this however it returns all students enrolled in the course. Where if the student has not been enrolled there is no NULL pid.
SELECT e.user_id, e.full_name, es.student
FROM employees e LEFT OUTER JOIN
enrolled_students es
ON e.user_id = es.student AND es.pid = 40
WHERE e.level = 3 AND es.student IS NULL ;
First we have to check who does enrolled in the course, then we have to get the list of names containing the other names except the ones returned in the first part of the query. Something like this can be done for this purpose:
SELECT
e1.*
FROM
employee e1
LEFT JOIN
(SELECT
e.user_id
FROM
employee e
JOIN enrolled_student es ON e.user_id = es.user_id
WHERE
es.pid = 1) t ON e1.user_id = t.user_id
WHERE
t.user_id IS NULL;
Try this:
select id from users where id not in (select user_id from enrolled where pid = 1)
Selects all users, which are not enrolled to course 1.

SQL join and sub query in sql

I have a table employee having columns id (primary key), *employee_name* and another table called employee_works with columns *employee_id* (foreign key referencing employee.id), *start_date* (datetime), *finish_date* (datetime).
Here are some datas for employee table:
**id** **employee_name**
1 employee A
2 employee B
3 employee C
4 employee D
5 employee E
6 employee F
7 employee G
employee_works table:
1 2010-01-01 00:00:00 NULL
2 2010-01-01 00:00:00 2010-01-10 10:00:00"
2 2010-01-13 00:00:00 2010-01-15 10:00:00"
2 2010-01-31 00:00:00 NULL
4 2010-02-18 00:00:00 2011-01-31 00:00:00"
6 2010-02-18 00:00:00 NULL
NULL value means the employee still works.
I need to get a single query showing the list of persons in employee, if they worked with us, who still works in our company, who left and if possible, for how long they worked with us.
Example:
id employee_name status
1 Employee A Still with us
3 Employee C Never worked
4 Employee D Left
My attempt:
SELECT emp.id,emp.name,
CASE
WHEN occ.finish_date is NULL and occ.start_date is NOT NULL THEN 'Still working'
WHEN occ.finish_date is NULL and occ.start_date is NULL THEN 'Never Worked'
WHEN occ.finish_date is NOT NULL and occ.start_date is NOT NULL THEN 'Left'
END
AS status
FROM employee AS emp
LEFT JOIN employee_works AS occ ON emp.id=occ.employee_id
GROUP BY emp.id, occ.finish_date
I also want to get the total no of days the employees have worked in another column?
The problem is that you have a group by but no aggregations for the definition of status. Mysql does not give you a syntax error. Instead, it gives you a random status:
Try something like this instead:
select id, name,
(CASE WHEN statusint = 3
THEN 'Still working'
WHEN statusint = 1 or statusint is null
THEN 'Never Worked'
WHEN statusint = 2
THEN 'Left'
END) AS status,
days_worked
from (SELECT emp.id, emp.name,
max(CASE WHEN occ.departure_date is NULL and occ.start_date is NOT NULL
THEN 3
WHEN occ.departure_date is NULL and occ.start_date is NULL
THEN 1
WHEN occ.departure_date is NOT NULL and occ.start_date is NOT NULL
THEN 2
END) AS statusint,
sum(datediff(coalesce(departure_date, curdate()), occ.start_date
) as days_worked
FROM employee emp LEFT JOIN
employee_works occ
ON emp.id=occ.employee_id
GROUP BY emp.id, emp.name
) eg
This "feature" of mysql is called hidden columns. Folks who write mysql (and many who use it) think this is a great feature. Many people who use other databases just scratch their heads and wonder why any database would act so strangely.
By the way, you should check if someone who is employeed multiple times gets assigned a new id. If so, your query might need more advanced name matching methods.
Try to simplify your condition.
SELECT a.*,
CASE
WHEN b.employeeID IS NULL THEN 'NEVER WORKED'
WHEN b.finish_date IS NULL THEN 'STILL WORKING'
WHEN DATE(b.finish_date) < CURDATE() THEN 'LEFT'
END as `Status`
FROM employee a
LEFT JOIN employee_works b
on a.id = b.employeeID