New Sql query solution - sql

person_id | manager_id | name |
| | |
-------------------------------
I have to display name of every person with manager name.
Yes its complete table. Thats all I have.

This one should give you all employees that have a manager, with employee_name and manager_name. Replace your_table by your table name.
If you want to get all persons, also that without manager, replace the JOIN by a LEFT JOIN. This would return NULL as manager_name for all persons without manager_id.
SELECT t1.name employee_name, t2.name manager_name
FROM [your_table] t1
JOIN [your_table] t2 ON ( t1.manager_id = t2.person_id )

Which SQL dialect? Here's some TSQL, but I'm vague to the actual question ("every person with manager name"); if you mean "given a manager name, list the people (reports)", then:
SELECT peon.[person_id], peon.[name]
FROM [thetable] mgr
INNER JOIN [thetable] peon
ON peon.manager_id = mgr.[person_id]
WHERE mgr.[name] = #name
ORDER BY peon.[name]
If you mean "list the people, along with their manager's name", then:
SELECT peon.[person_id], peon.[name], mgr.[name] AS [manager]
FROM [thetable] peon
LEFT OUTER JOIN [thetable] mgr
ON mgr.[person_id] = peon.manager_id
ORDER BY peon.[name]

SELECT person.name, manager.name
FROM table person, table manager
WHERE person.manager_id = manager.person_id

Related

Output the names of bosses who manage multiple employees

I have a database of personnel which has an EMPLOYEE_ID, EMPLOYEE_NAME and BOSS_ID. I'm trying to display the employee_name of all bosses who manage 3 or more people. The following query provides me with all the right BOSS_ID's.
SELECT BOSS_ID FROM PERSONNEL
GROUP BY BOSS_ID
HAVING COUNT(BOSS_ID) >= 3
However I wish to only display the EMPLOYEE_NAME of the bosses, not their BOSS_ID. I tried this, but it produced no names at all.
SELECT EMPLOYEE_NAME FROM PERSONNEL
GROUP BY EMPLOYEE_NAME
HAVING COUNT(BOSS_ID) >= 3
Any help would be greatly appreciated.
To get the Manager Name your can do Self Join.
In the below example to get the Manager name you need to get it from P2 Reference.
SELECT DISTINCT P2.EMPLOYEE_NAME AS ManagerName
FROM PERSONNEL P1
JOIN PERSONNEL P2 ON P1.BOSS_ID = P2.EMPLOYEE_ID
GROUP BY P2.EMPLOYEE_NAME
HAVING COUNT(P1.BOSS_ID) >= 3
You can do a JOIN on the same table to obtain the boss's name.
SELECT p.Employee_name, b.Employee_name as "Boss Name"
FROM personnel p
INNER JOIN personnel b ON b.Employee_ID = p.Boss_ID
you can try using a subquery.
SELECT Employee_name
FROM PERSONNEL
where BOSS_ID IN (
SELECT BOSS_ID FROM PERSONNEL
GROUP BY BOSS_ID
HAVING COUNT(BOSS_ID) >= 3
)
db fiddle

How to add and modify a column in SQL that is specific to the table

I have the following table
Name ReportsTo Position
-----------------------------
Jill null manager
Nathan Jill junior
I want to add another column in the end that says the title of the person they report to so it would look like this.
Name ReportsTo Position Boss
-------------------------------------
Jill null manager none
Nathan Jill junior manager
My current code is (to get the first table I displayed)
SELECT
t1.Name, t1.ReportsTo, t1.Position
FROM
yourTable t1
WHERE
ReportsTo = 'Jill' OR ReportsTo IS NULL
To bring in the immediate managers of each employee you may use a self join:
SELECT t1.Name, t1.ReportsTo, t1.Position, COALESCE(t2.Position, 'none') AS Boss
FROM yourTable t1
LEFT JOIN yourTable t2
ON t2.Name = t1.ReportsTo;
Demo

Oracle SQL - Return rows with a value based on multiple values in a second field

I need to return the rows that contain the employee names (in one field) who are only classified as Managers (not as Workers, or as Managers and Workers).
Managers and Workers values are in a second field.
So it might look like this:
+----------+------------+
| 'Miller' | 'Manager' |
| 'Jones' | 'Manager' |
| 'Jones' | 'Worker' |
+----------+------------+
In this instance I just want it to return 'Miller'.
I can get one or both, but not the ones where an employee is only classified as a Manager.
Any thoughts?
One method uses aggregation:
select name
from t
group by name
having min(classification) = max(classification) and min(classification) = 'manager';
Count the number of titles. If they have a title of 'Manager' and there's only one title, select the individual:
SELECT *
FROM PEOPLE p
INNER JOIN (SELECT NAME, COUNT(TITLE) AS TITLE_COUNT
FROM PEOPLE
GROUP BY NAME) c
ON c.NAME = p.NAME
WHERE p.TITLE = 'Manager' AND
c.TITLE_COUNT = 1;
dbfiddle here
Method with a subquery which should work well when there are not only 'Managers' and 'Workers' in the table:
SELECT t1.name FROM t t1
WHERE
t1.classification='Manager'
AND NOT EXISTS (
SELECT 1 FROM t t2 WHERE t1.name=t2.name AND t2.classification='Worker'
)

Joining same table multiple times

I have 2 tables Person an Department - where each person has multiple departments registered against him.
Person
id|name|dept1|dept2|dept3
1 |Jane|100 |102 |106
Dept
id |Name
100|Accounts
...
102|HR
...
106|Admin
Whats the most elegant sql to display Jane's record as follows:
Jane|Accounts|HR|Admin
Use this. And work on your naming convention to make all column names unique independent of table.
SELECT
Person.id, Person.name, dept1.Name, dept2.Name, dept3.Name
LEFT JOIN Dept dept1 ON dept1.id = Person.dept1
LEFT JOIN Dept dept2 ON dept2.id = Person.dept2
LEFT JOIN Dept dept3 ON dept3.id = Person.dept3
Something like this will let you join the same table multiple times. You just give each join a different alias
SELECT *
FROM Person AS P
INNER JOIN Dept AS D1 ON P.dept1 = D1.id
INNER JOIN Dept AS D2 ON P.dept2 = D2.id
WHERE P.name = 'Jane'
Ideally you would normalise the data in your Person table and have a linking table between Person and Dept e.g. PersonDepartmentLinking (or whatever convention you have for linking table naming conventions), assuming you have any control over the schema and it's possible to add the relationship that way.
You can use STUFF in this case
Select name,
Stuff((Select distinct ', ' + cast(Name as varchar(20))
From #Dept t2
Where t2.Id = t1.Id
FOR XML PATH('')),1,1,'')
From Person t1
The only way that I know is a join for each column.
But if you are in the way of designing the tables, i suggest you to normalize the DB.
If a person need an extra dept column, you need to alter the table to add a new property of person.
For me, 3 entities are needed:
- Person
- Department
- person_department_assignation

How do I simplify this query?

so my main goal with this query is to select all departments and employees under a manager named Mario Souza.
SELECT d.deptname,e.name FROM employee e JOIN department d ON e.dept = d.deptnum WHERE idmanager IN(
SELECT id FROM employee WHERE name = 'Mario Souza'
) AND manager IN(
SELECT id FROM employee WHERE name = 'Mario Souza'
)
And it's working, but is there a way I could store the first IN result so I could use it later after the AND operator?
You can use EXISTS to match on multiple columns.
WHERE EXISTS
(
SELECT *
FROM employee AS manager
WHERE manager.name = 'Mario Souza'
AND manager.id = e.idmanager
AND manager.id = d.manager
)
You could use a JOIN with employee table. Simply put both manager and idmanager in ON clause.