Nested query in MySQL using select statement - mysql

I am having trouble with the activity I have in MySQL.
Below are the tables of my employee database, and I want to show the dept_name column from the department table, first_name and last_name from the employee table, and the title_name from the title table.
ER diagram for employee database
The instruction is to query it using a select statement. If anyone knows how to do it, please help me :< thank you so much.

You can use JOIN or write as below
SELECT e.first_name, e.last_name, d.dept_name, t.title_name
FROM employee e, department d, title t, emp_dept ed, emp_title et
WHERE
e.emp_no = ed.emp_no AND ed.dept_no = d.dept_no
AND e.emp_no = et.emp_no AND et.title_no = t.title_no

Related

JOIN subquery and different reault

I was writing an exercise about "Write a query to find the names (first_name, last_name) of the employees who are not supervisors"
I write it on my own and when i check the result or both, mine has less rows than the other.
I was using the JOIN function and the other doesn't.
I want help to know why two results are so different.
Thanks
the one i use join
SELECT
first_name, last_name
FROM
employees AS E
JOIN
departments AS D ON E.department_id = D.department_id
WHERE
NOT EXISTS( SELECT
0
FROM
departments
WHERE
E.manager_id = D.manager_id)
order by last_name;
the one doesn't use join
SELECT
b.first_name, b.last_name
FROM
employees b
WHERE
NOT EXISTS( SELECT
0
FROM
employees a
WHERE
a.manager_id = b.employee_id);
The big problem is that the NOT EXISTS subquery is referencing rows from the joined table. The manager_id column is qualified with D., and that's a reference to the joined table, not the table in the FROM clause of the subquery.
E.manager_id = D.manager_id
^^^^^^^ ^
We also suspect that an employee's supervisor is recorded in the employee row, as a reference to another row in the the employee table. But we don't have the schema definition or any example data, so we're just guessing.
It seems like there would be a supervisor_id in the employee table...
SELECT e.first_name
, e.last_name
, e.department_id
, d.department_id
FROM employees e
WHERE NOT EXISTS
( SELECT 1
FROM employees s
WHERE s.id = e.supervisor_id
)
ORDER
BY e.last_name
, e.first_name
It's also possible that some rows in employee have a value in the department_id column that don't have a matching row in the department table. If there is no matching row in department, the inner join will prevent the row from employee from being returned.
We can use an outer join when we want to return rows even when no matching row is found in the joined table. If we want to involve the departments table, because a "supervisor" is defined to be an employee that is the manager of a department, we can employ an anti-join pattern...
SELECT e.first_name
, e.last_name
FROM employees e
LEFT
JOIN departments d
ON d.manager_id = e.employee_id
WHERE d.manager_id IS NULL
ORDER
BY e.last_name
, e.first_name
Again, without a schema and some sample data, we're just guessing.
This query can be written using only Employees table, but in your query you have joined the employees table with department table. A query should be written with the minimal amount of tables that suffice your expected output, joining unnecessary tables may result in wrong out puts.
In this case you are joining Employees with department here what if there is no Department_ID in employee table for some employees, so those data will be dropped in the join and result won't be the expected.

How to get records by using 3 tables or work with 3 tables?

I have been asked this question in an interview. I have tried so hard, but unfortunately was not able to get it right.can anybody help me with this?
Retrieve the last name, first name, dept name of that employee using these tables.I am writing down the tables and columns.however, i am not writing that dummy data.
Employee- (id, last name, first name, DOB, SSN) and some other columns(not useful).
Dept - (D_id, dept name)
Emp_Dept - (id, D_id)
You can try this solution for your problem :
Query :
SELECT E.last_name, E.first_name, D.dept_name
FROM Employee AS E
-- Get employee dept
INNER JOIN Emp_Dept AS ED
ON ED.id = E.id
-- get dept data
INNER JOIN Dept AS D
ON D.id = ED.D_id
I hope it will help you.
But this query doesn't return value of employee without dept. If this is necessary you should use LEFT JOIN instead of INNER JOIN

How to check if a particular mapping exists in a one-to-many mapping table

I am having a table that maintains the mapping of an EMPLOYEE_ID to the one or more ROLE_IDs that the employee can be assigned with. The ROLE_ID is a primary key of the ROLE table.
Now, I am trying to find if a particular employee is a Team Leader (ROLE_ID = 2) or not. That is, in essence, trying to find if the particular mapping combination of (EMPLOYEE_ID, 2) exists in the mapping table.
Currently, I am using the below query to achieve this:
SELECT E.NAME AS `EMPLOYEE_NAME`,
EXISTS( SELECT 1 FROM `EMPLOYEE_ROLE` WHERE
(`EMPLOYEE_ROLE`.`EMPLOYEE_ID` = `E`.`EMPLOYEE_ID`)
AND (`EMPLOYEE_ROLE`.`ROLE_ID` = 2)) AS `IS_TEAM_LEADER`
-- Assume some other column shall be selected from ER table,
-- hence necessitating the JOIN on ER
FROM EMPLOYEE E
JOIN EMPLOYEE_ROLE ER ON (ER.EMPLOYEE_ID = E.EMPLOYEE_ID)
GROUP BY E.EMPLOYEE_ID;
Although this seems to get the job done, I am looking for a more efficient approach, as the subquery in its current form seems redundant. Not sure if it's relevant, but can FIND_IN_SET or some such function be used?
Can anyone suggest a solution, as I am interested in the best-performing approach?
EDIT 1: I have intentionally used the JOIN EMPLOYEE_ROLE with the intention that some other column also may be picked from the ER table. So, I am looking for optimising the subquery, while keeping that join intact. Hence, the statement "current subquery in its current form seems redundant".
SQLFiddle: http://sqlfiddle.com/#!9/2aad3/5
Either use the exists subquery or use join, but you should not use both in one query.
I would use the join approach, since it's easy to get role related data if necessary:
SELECT E.NAME AS `EMPLOYEE_NAME`,
FROM EMPLOYEE E
INNER JOIN EMPLOYEE_ROLE ER ON (ER.EMPLOYEE_ID = E.EMPLOYEE_ID)
WHERE ER.ROLE_ID=2;
If you need a list of all employees with a field indicating if that employee is IS leader or not, then use left join instead of inner:
SELECT DISTINCT E.NAME AS `EMPLOYEE_NAME`, IF(ER.ROLE_ID IS NULL, 'NOT IS Leader','IS Leader') AS IsISLeader
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE_ROLE ER ON ER.EMPLOYEE_ID = E.EMPLOYEE_ID AND ER.ROLE_ID=2;
"best performing" --
CREATE TABLE `EMPLOYEE_ROLE` (
`EMPLOYEE_ID` INT NOT NULL,
`ROLE_ID` INT NOT NULL,
PRIMARY KEY(`EMPLOYEE_ID`, ROLE_ID),
INDEX(`ROLE_ID` EMPLOYEE_ID)
) ENGINE=InnoDB;
Why.
Beyond that, see #Shadow's answer.
I include EMPLOYEE_ID in the SQL in case same NAME found for different EMPLOYEE_ID, also use LEFT JOIN in case some employee does not have roles:
SELECT E.EMPLOYEE_ID, E.NAME, SUM(IF(R.ROLE_ID=2,1,0)) IS_TEAM_LEADER
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE_ROLE R ON E.EMPLOYEE_ID = R.EMPLOYEE_ID
GROUP BY 1,2
Simply use The FK relationship
create a Role Table as
table role{
RoleID
RoleName
Status
...}
and edit the employee table as
table employee{
ID
name
...
}
create table employeerole
table employeerole{
ID
roleID
employeeID
}
now you can manage multiple roles to each employee with normalization rules too
now you can use the query
SELECT employee.ID, employee.Name, employeerole.roleid FROM role
INNER JOIN employeerole ON role.RoleID = employeerole.roleid INNER
JOIN dbo.employee ON dbo.employeerole.employeeid = dbo.employee.ID
WHERE employeerole.roleid = 2
the table role has ID 2 and Name for example is team leader or manager
now this query is fully optimized and will give you best results
If I understand you correctly, you're trying to get all employees, with all of their roles, plus an additional column indicating whether they're a Team Leader. If so, you just need to join on EMPLOYEE_ROLE twice, the second being a LEFT JOIN just to check for a specific role:
SELECT E.NAME, ER.ROLE_ID, ER2.EMPLOYEE_ID IS NOT NULL AS `IS_TEAM_LEADER`
FROM EMPLOYEE E
JOIN EMPLOYEE_ROLE ER ON ER.EMPLOYEE_ID = E.EMPLOYEE_ID
LEFT JOIN EMPLOYEE_ROLE ER2 ON ER2.EMPLOYEE_ID = E.EMPLOYEE_ID AND ER2.ROLE_ID = 2;
SQL Fiddle: http://sqlfiddle.com/#!9/2aad3/9/0
Here is the query to get all the employee who belongs to a specific role
SELECT e.NAME FROM EMPLOYEE e right join (SELECT EMPLOYEE_ID FROM
EMPLOYEE_ROLE WHERE ROLE_ID=2) er using(EMPLOYEE_ID);

SQL statement with JOIN and WHERE clause

I'm new to SQL and trying to solve this problem with two tables Employee and Department. I want display the names of all the employees of 'HR' and 'Sales' departments.
Tables are Employee (emp_id, emp_name, dept_id) and Department (dept_id, dept_name).
Thanks!
Try this:
Select e.emp_name from
Employee e inner join Department d
on e.dept_id = d.dept_id
Where d.dept_name in ('HR','Sales');
This query will compare the dept_id of Employee table and Department table. Those values matched will be returned. then out of all the fields you will select the emp_name and limit the employees belonging to HR and Sales department using the where clause.
As you only want to display employee data, only select from that table. The rest is criteria. You want their department to be either 'HR' or 'Sales', so the straight-forward way of writing this is the IN clause (you could also use the EXISTS clause):
select emp_name
from employee
where dept_id in
(
select dept_id
from department
where dept_name in ('HR', 'Sales')
);
I think this is more easy to read than to join the tables first, only to use one as a filter for the other.
select Employee.emp_name [Emplyee Name] from Employee inner join Department on Department.dept_id=Emplyee.emp_id where Department.dept_name='HR'
You can get like this,
SELECT [emp_name] FROM [dbo].[Employee] AS E
INNER JOIN [dbo].[Department] AS D
ON D.dept_id=E.dept_id
WHERE D.dept_name='HR' OR D.dept_name='Sales'

Complex MySQL query selecting all items which have all attributes

I got the following schema:
employees(emp_no, birth_date, first_name, last_name,...)
departments(dept_no, dept_name)
dept_emp(emp_no, dept_no)
and I am trying to find a query that returns the first and last name and employee number of the employees that have worked in all departments. Any ideas?
P.S.: emp_no and dept_no are the primary keys.
SELECT
e.first_name,
e.last_name,
e.emp_no
FROM employees e
INNER JOIN dept_emp dn ON dn.emp_no = e.
INNER JOIN departments d ON d.dept_no = dn.dept_no