How do I simplify this query? - sql

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.

Related

SELECT and JOIN to return only one row for each employee

I have a user table that stores the employeeId, lastName, firstName, department, hire date and mostRecentLogin.
I have another table that stores the employeeId, emailAddress.
The emailAddress table can have multiple rows for an employee if they have multiple email addresses.
I'm trying to return results that only show one row for each employee. I don't care which email address, just as long as it only picks one.
But all the queries I've tried always return all possible rows.
Here is my most recent attempt:
select *
from EmployeeInfo i
left join EmployeeEmail e ON i.employeeId = e.employeeId
where i.hireDate = 2015
and employeeId IN (
SELECT MIN(employeeId)
FROM EmployeeInfo
GROUP BY employeeId
)
But then again, this returns all possible rows.
Is there a way to get this to work?
Use a sub-query instead of a join:
select *
, (select top 1 E.EmailAddress from EmplyeeEmail E where E.employeeId = I.employeeId)
from EmployeeInfo I
where I.hireDate = 2015;
Note: If you change your mind and decide you do have a preference as to which email address is returned then just add an order by to the sub-query - otherwise it is truly unknown which one you will get.
This should work.
SELECT *
FROM EmployeeInfo
Left JOIN EmployeeEmail
ON EmployeeInfo.employeeId = EmployeeEmail.employeeId
WHERE EmployeeInfo.hireDate = '2015'
GROUP BY EmployeeInfo.employeeId;

How to use subqueries in oracle

Hello I'm trying to solve this question with a subquery:
Select names, service number, jobs and salaries of
people working in the same city as HAVET. (havet is a name)
And I have only two table the first one is the emp table with the column (noserv, name, job, salaries) and the second one is the SERV table with the column (noserv, nameserv, city)
I know that I have to use a subquery but I don't know how to do it.
Semi-pseudocode (CTE won't work, obviously).
with emp (noserv, name, job, salaries),
serv (noserv, nameserv, city)
-- This is what you're looking for, I presume
select e.*
from emp e join serv s on e.noserv = s.noserv
where s.city = -- subquery returns city where HAVET lives
(select s1.city
from serv s1 join emp e1 on e1.noserv = s1.noserv
where e1.name = 'HAVET'
);
Try this:
-- This is a normal query with a left join
select *
from emp e
left join s on e.noserv = s.noserv
where s.city =
-- get Havet's city from the subquery.
(select s.city
from emp e
left join s on e.noserv = s.noserv
where e.name = 'HAVET')
Try this one, change the column name according to your table and column names.
Select e.name,e.serviceNubmer,e.Job,e.salaries
from emp e,serv s
where
e.noserv = s.noserv
and s.city ='HAVET';

For each employee with dependent(s), list their last name and the name of their oldest dependent. Display the results in sequence by dependent’s name

SELECT E.Lname,D.Dependent_name
FROM EMPLOYEE as E , DEPENDENT as D
WHERE
E.ssn=D.Essn
AND
D.Bdate = (SELECT MIN(Bdate) FROM DEPENDENT
WHERE Bdate IS NOT NULL)
This does work but it just show for 1 employee
Link to DB:
https://www.db-fiddle.com/f/xhEj2sAgdTMABBkCtJvmoC/0#&togetherjs=z3CKywAccH
As it is, your subquery returns the minimum bdate over the whole table, resulting in only the empolyee that has the oldest dependant being filtered in. As commented by #PM77-1, you would need to correlate your subquery with the employee that you are currently processing.
SELECT E.Lname,D.Dependent_name
FROM
EMPLOYEE as E
INNER JOIN DEPENDENT as D ON E.ssn=D.Essn
WHERE D.Bdate = (
SELECT MIN(Bdate)
FROM DEPENDENT
WHERE Essn = E.ssn
)
ORDER BY 2, 1;
Another, probably more efficient option, is to use Postgres window function ROW_NUMBER() to assign a row number to each record in the group made of all dependents of a given employee, ordered by date of birth. An outer query can then filter in the first record in each group :
SELECT x.lname, x.dependent_name
FROM (
SELECT
e.lname,
d.dependent_name,
ROW_NUMBER() OVER(PARTITION BY e.ssn ORDER BY d.bdate) rn
FROM employee e
INNER JOIN dependent d ON e.ssn = d.essn
) x WHERE x.rn = 1
ORDER BY 2, 1;
Demo on DB Fiddle
select a.lname, a.dependent_name
from
(
select e.lname, d.dependent_name, d.bdate, e.ssn
from employee e, dependent d
where e.ssn=d.essn
order by d.dependent_name, e.lname
)a
where a.bdate= (select min(bdate) from dependent
where dependent.essn= a.ssn)
order by a.lname;
This displays the names of three employees > Smith, Wallace, Wong with their corresponding eldest dependents > Elizabeth, Abner, Joy.
Hope this solves the problem.

How to check if there exist only one record for a certain Id

How to check if there exist only one record for a certain Id
I have two tables called Tbl_Company and Tbl_Employee
I am fetching employees as follows-
SELECT DISTINCT emp.employee_id
FROM Tbl_Company comp
, Tbl_Employee emp
WHERE
emp.company_id = comp.company_id
AND emp.company_id = 1234;
This query returns exactly one value.
How can I make sure that above query returns exacly one value for any comany_id I enter.
I tried using solutions given in This post with no success.
Is there any simpler way to do this.
this would return one row per company
SELECT comp.companyid, max(emp.employee_id) lastEmployeeID
FROM Tbl_Company comp
, Tbl_Employee emp
WHERE
emp.company_id = comp.company_id
AND emp.company_id = 1234
GROUP BY comp.companyid
the following query is simple and flexible. it will return a list of all employees which are alone in their companies (returned with full employee information).
you can check if a defined company has one lonely employee by enable condition about company or you can check if employee is a lonely employee by enabling employee condition.
SELECT emp.*
FROM Tbl_Company comp
/*, Tbl_Employee emp*/
WHERE (emp.company_id , 1) in (select t.company_id, count(t.employee_id) from Tbl_Company t )
--AND emp.company_id = 1111 /*filter conditions on company_id*/
--AND emp.employee_id = 1234/*filter conditions on employee_id*/;
I have solved this by using ans by #davegreen100 in comment
SELECT comp.companyid, count(distinct emp.employee_id),
FROM Tbl_Company comp
, Tbl_Employee emp
WHERE
emp.company_id = comp.company_id
AND emp.company_id = 1234
GROUP BY comp.companyid
This will give me the count of employees per company

SQL subquery Total/Count

I am trying to write a query that lists the name of a manager and the number of people they manage.
In the Manager table we have the managers name and id.
In the Employee table we have the employees name, id and managerID.
I don't understand how to get the count of the employees that a manager manages.
SELECT COUNT(e.EmpID), m.ManagerID
FROM Employee e
INNER JOIN Manager m
ON e.ManagerID= m.ManagerID
GROUP BY m.ManagerID
SELECT m.Name, COUNT(e.id) AS NumberOfEmployeesManaged
FROM Manager m INNER JOIN Employee e ON m.id = e.managerID
GROUP BY m.Name
That should do it I think, just a simple count of the employee ids after joining the manager and employee tables, grouped on manager name.
SELECT count(emp.empid), mgr.managerid
FROM Employee emp
INNER JOIN Manager mgr ON emp.managerid=mgr.managerid
GROUP BY mgr.managerid;
I don't know if you can use the COUNT aggregator in a JOIN. But you can run 2 queries. One would select the manager's name & id. The 2nd would look like this:
$id = the manager's id
SELECT COUNT(*) FROM Employee WHERE managerID=$id
Alternately, you could not use COUNT and run a query like this:
SELECT id FROM Employee WHERE managerID=$id
Then the # of resulting rows would be the count of employees managed by the manager.