Sql Query! Can someone explain this? - sql

Q1 : List employees who have the biggest salary in their departments
Q2 : List employees that don't have a boss in the same department
Q1 Answer)
Select e.name, Max_Sal.Sal
From Employees e
JOIN (Select d.DepartmentID,max(e.Salary) As Sal
From Employees e
JOIN Departments d ON e.DepartmentId=d.DepartmentId
Group by d.departmentID
) As Max_Sal
ON e.DepartmentId=Max_Sal.DepartmentID
and e.Salary=Max_Sal.Sal;
In Q2, I don't understand the question, [don't have a boss in the same department]. How to know boss is in which department?

Q2 : List employees that don't have a boss in the same department
There is a slight trick to this question.
1 - Join
SELECT e.*
FROM Employees e
LEFT OUTER JOIN Employees b on e.BossId = b.EmployeeId
Notice the following:
We've used the Employees table twice, but I've given them separate names. e is every employee; and b is that employee's boss.
We use a LEFT OUTER JOIN to account for the possibility that an employee does not have a boss (b will be NULL) If we had used an INNER JOIN, the employees with no boss would have been omitted from the result.
Now, we have a table of every employee, connected to their boss. But we still need to filter the list as requested.
2 - Filter
There are three possible states that an employee can be in:
They have no boss.
They have a boss, who works in the same department.
They have a boss, who works in a different department.
It's important to realize that the requested output needs to contain both the employees in situation 3 and the employees in situation 1. We should only omit the employees in situation 2.
Using pseudo-SQL, this means your query should look like this:
SELECT *
FROM the_data
WHERE
situation_1_applies
OR
situation_3_applies
The individual filters are not that hard to write:
SELECT e.*
FROM Employees e
LEFT OUTER JOIN Employees b on e.BossId = b.EmployeeId
WHERE
-- situation_1_applies
-- When b is NULL, all of b's columns are NULL
b.DepartmentId is NULL
OR
-- situation_3_applies
b.DepartmentId <> e.DepartmentId

Don't have a boss in the same department, so you can think bossID in Employees table is null. So you can write an SQL query for a group all of the people have the same department who have the bossID is null :), So it not real because employees have to have a boss (not null), If you show me full field of table, maybe I will show you exactly my answer.
In the other hand, you can think, They have the same bossID, so your mission will write an SQL query for a group all of the people have the same bossID but they have a different department.
I have an example MySQL query (for same bossID but different department):
SELECT * FROM Employees as e
INNER JOIN department d ON d.departmentId = e.deparmentId
WHERE e.DepartmentID in (
SELECT DepartmentID
FROM Employees
GROUP BY DepartmentID
HAVING COUNT(*) = 1 /* it's fixed */
) AND e.BossID = 2 /* any value of bossID you want, you can join it with Boss table */
===== Update my answer =====
I have an idea for the question.
Anyone must have a boss, and boss also is an employee in table SQL.
' employeeName ' department name ' boss name
--------------------------------------------------------
' King ' Director '
' Victor ' Marketing ' King
' Angela ' Product ' King
' Ken ' Marketing ' Victor
' LaLa ' Marketing ' Victor
' Jery ' Business ' Ken
And because don't have a boss in the same department -> their department can't have their boss. => the result as the following table:
' employeeName ' department name ' boss name
--------------------------------------------------------
' King ' Director '
' Victor ' Marketing ' King
' Angela ' Product ' King
' Jery ' Business ' Ken
If you have a right way to understand this question, you can post here for everyone can understand. Thanks

Related

SQL hierarchyid type issue

The full task sounds like this: Display the content of employees whose immediate supervisor is younger and less employed in the company.
Columns:
Manager Name | Date of hiring a manager | Head's date of birth
Employee name | Employee hiring date | Employee's date of birth
I already broke my head here:
SELECT
LastName + ' ' + FirstName AS SupervisorFullName,
HireDate,
BirthDate,
(SELECT LastName + ' ' + FirstName
FROM HumanResources.Employee AS subHrE
WHERE HrE.OrganizationNode.IsDescendantOf(subHrE.OrganizationNode) = 1
AND HrE.OrganizationLevel = HrE.OrganizationNode.GetLevel() + 1) AS EmployeeFullName,
(SELECT HireDate
FROM HumanResources.Employee AS subHrE
WHERE HrE.OrganizationNode.IsDescendantOf(subHrE.OrganizationNode) = 1
AND HrE.OrganizationLevel = HrE.OrganizationNode.GetLevel() + 1) AS HireDateEmp,
(SELECT BirthDate
FROM HumanResources.Employee AS subHrE
WHERE HrE.OrganizationNode.IsDescendantOf(subHrE.OrganizationNode) = 1
AND HrE.OrganizationLevel = HrE.OrganizationNode.GetLevel() + 1) AS BithDateEmp
FROM
HumanResources.Employee as HrE
JOIN
Person.Person as P ON HrE.BusinessEntityID = P.BusinessEntityID
ORDER BY
SupervisorFullName ASC
Output
AdventureWork2016 db is used for work
Full Schema AW2016
There's definitely a certain way to think about use of hierarchyid that, once you get the hang of it, opens a lot of possibilities. Here's what I came up with:
WITH FullPerson AS (
SELECT CONCAT_WS(' ', p.FirstName, p.MiddleName, p.LastName) AS [FullName],
e.HireDate,
e.BirthDate,
e.OrganizationNode
FROM HumanResources.Employee AS e
JOIN Person.Person AS p
ON p.BusinessEntityID = e.BusinessEntityID
)
SELECT
manager.OrganizationNode.ToString(),
manager.FullName,
manager.HireDate,
manager.BirthDate,
subordinate.OrganizationNode.ToString(),
subordinate.FullName,
subordinate.HireDate,
subordinate.BirthDate
FROM FullPerson AS subordinate
JOIN FullPerson AS manager
ON subordinate.OrganizationNode.GetAncestor(1) = manager.OrganizationNode
WHERE manager.HireDate > subordinate.HireDate
AND manager.BirthDate > subordinate.BirthDate;
Breaking it down, I create a common table expression to join Employee and Person as I'll need columns from both tables for both subordinates and their managers. The real trick is the join condition. subordinate.OrganizationNode.GetAncestor(1) = manager.OrganizationNode says "take the subordinate's OrganizationNode and go one level up the tree". What's amazing to me is that this sort of query can be supported by indexes and indeed there is an index on that column in the AdventureWorks schema! In addition to the columns you asked for, I added a human-readable representation of OrganizationNode to help with the visualization of how the data relates.

How to find a destinct values in a table that are larger than all values that reference it?

I need to find the names of bosses who were hired after all the hired date of all their subordinates.
Here is what I have got so far:
SELECT DISTINCT
TRIM(boss.first_name || ' ' || boss.last_name) AS NAME,
boss.phone_number AS phone
FROM
HR.employees e
INNER JOIN HR.employees boss ON (boss.employee_id = e.manager_id)
WHERE
boss.hire_date > MIN(e.hire_date)
AND boss.hire_date > MAX(e.hire_date);
The idea was to check that the boss.hire_date is larger than the earliest and latest hire_date of his subordinates.
However I get following error message:
ORA-00934: group function is not allowed here
Any idea how I have to restructure the query?
What about using a subselect to get the maximum hire date of all employees for a given boss and check that in the WHEREclause?
You may need to filter this list for employees, that are not a boss.
Like:
SELECT boss.*
FROM hr.employees boss
WHERE boss.hire_date > (SELECT MAX(e.hire_date)
FROM hr.employees e
WHERE boss.employee_id = e.manager_id);
This should work better
SELECT TRIM(boss.first_name || ' ' || boss.last_name) AS NAME,
boss.phone_number AS phone
FROM HR.employees boss
INNER JOIN
(
SELECT e.manager_id, MAX(e.hire_date) AS Max_hire_date
FROM HR.employees e
GROUP BY e.manager_id
) m ON m.manager_id=boss.employee_id
WHERE boss.hire_date > m.Max_hire_date
Note that I have supposed that a boss can't manage itself. In an usual hierarchical database, the top manager has its manager_id field = NULL. If in your data a boss can have its manager_id =i ts own employee_id, it wont work.

How to display last names and numbers of all managers together with the number of employees that are his/her subordinates

This is the schema
\,
I try using inners but the results were trash
SELECT
employees.last_name AS last_name,
COUNT(employees.job_id) AS EMPLOYEES_Subordinates,
COUNT(employees.manager_id) AS Manager_Numbers
FROM
employees left
JOIN departments ON departments.manager_id = employees.manager_id
GROUP BY
employees.last_name
ORDER BY
EMPLOYEES_Subordinates desc;
( i really don't know how to show you the tables from hr)
If any 1 has the HR in Oracle Database and have time to help me , I gladly appreciate .
not quite sure but try something like this:
SELECT
e.LAST_NAME
,(SELECT COUNT(ee.EMPLOYEE_ID) FROM EMPLOYEES ee WHERE ee.MANAGER_ID = e.EMPLOYEE_ID) AS 'NUMBER OF WORKERS'
FROM EMPLOYEES e
WHERE MANAGER_ID IS NULL

SQL: List the employees who report to those employees who report to (____)

from this table..
Employees Table
Question: List the employees who report to those employees who report to Diane Murphy. Use the CONCAT function to combine the employee's first name and last name into a single field for reporting.
My non-working query..
SELECT employeeNumber, CONCAT(firstName, ' ', lastName), reportsTo
FROM Employees
WHERE reportsto= 1002
AND WHERE (SELECT CONCAT(firstName, ' ', lastName), reportsTo
FROM employees
WHERE reportsTo= 1056 AND 1076);
I am really confused by this question to be honest.
1002= Diane Murphy
1056= Mary Patterson
1076= Jeff Firrelli
Based on my understanding, im trying to query this based on a hierarchal system.
I know that both Mary and Jeff report to Diane Murphy and i can look at the table to see who reports to Mary and Jeff, but im lost exactly i go about querying this.
Any help would be appreciated!
Thank you.
SELECT A.employeeNumber, CONCAT(A.firstName, ' ', A.lastName), A.reportsTo
FROM Employees A
INNER JOIN Employees B ON A.reportsTo = B.employeeNumber
WHERE B.reportsto = 1002
Alias B and condition will fetch employees reports to 1002 & thus you will get employees who reports to 1056 & 1076.
This should do what you want:
select e1.employeeNumber, CONCAT(e1.firstName, ' ', e1.lastName), e1.reportsTo
from Employees as e1
inner join Employees as e2 on e1.reportsTo = e2.employeeNumber
where e2.reportsTo = 1002

self join condition

I have a confusion in self join condition
eg:i have a table named as 'employee' and column as employeeid,name,managerid
just a basic syntax
select e.employeeid,m.managerid
from employee e
left join employee m
**on e.managerid=m.employeeid
or e.employeeid=m.managerid**
please tell me differnce between the text with in **
I think your query is wrong to start with - right now you're getting the employee ID of the employee and the manager ID of the manager. So you're skipping a "generation"
I think you want:
select e.employeeid, m.employeeid
from employee e
left join employee m
on e.managerid=m.employeeid
That will give you the employee IDs in the first column and their manager's ID in the second column.
The second one would be the opposite:
select e.employeeid, m.employeeid
from employee e
left join employee m
on e.employeeid=m.managerid
Would give you the manager ID in the first column and their employee's IDs in the second column. In that case it would make more sense to swap the m and e aliases assuming they stand for manager and employee but that won't change the result.
the first part of your where
e.managerid=m.employeeid
will get your subordinate employees
and the second part
e.employeeid=m.managerid
will get your manager.
selecting m.managerid in your query doesn't really make sense.. if you look at this sample data and query it might make more sense to you.
CREATE TABLE employee (
employeeid INT,
managerid INT
)
INSERT INTO employee
VALUES (1,NULL),
(2,1),
(3,1),
(4,2),
(5,4);
SELECT e.employeeid employee,
m.employeeid relatedemployee,
CASE WHEN e.managerid = m.employeeid THEN 'manager'
ELSE 'employee'
END AS relationship
FROM employee e
LEFT JOIN employee m ON e.managerid = m.employeeid
OR e.employeeid = m.managerid
output:
employee relatedemployee relationship
----------- --------------- ------------
1 2 employee
1 3 employee
2 1 manager
2 4 employee
3 1 manager
4 2 manager
4 5 employee
5 4 manager