will this sql work - sql

Write ONE SQL statement that prints the name of all employees and their department numbers for all salaried employees who satisfy all of the following conditions:
Work on 2 projects,
Do not make $30000,
Their department manager and supervisor have the same name (Note: since name is not the pkey of employee tables, this requirement does not mean these two individuals are the same person).
Note that supervisor is not the manager of the department
SQL code:
select
ename, d#
from
employee, department
where
count(p#) = 2
and salary < 30000
and cname, d# in (select ename, d#
from employee, department
where employee.cname = depatment.cname);

This would be a good start for you, since there is some data missing about managers and supervisors (and generally you haven't provided any schema):
select ename
from employee e
join department d on e.cname = d.cname
where salary < 30000
group by ename
having count(p#) = 2
It will show up every employee with salary below 30K that works on 2 projects.
You're likely to need more joins/subqueries to achieve your desired output.

Related

matching pair of employees in a same department

I'm trying to make a list of employees working in a same department like:
employeeName
department
employeeName
Tim
2
kim
Tim
2
Jim
Kim
2
Tim
Kim
2
Jim
Jim
2
Kim
Jim
2
Tim
Aim
3
Sim
Sim
3
Aim
But the only thing i can do for now is:
SELECT emp_name, dept_code
FROM employee
WHERE dept_code IN (SELECT dept_code FROM employee);
employeeName
department
Tim
2
Kim
2
Jim
2
Aim
3
Sim
3
How can I make a list pairing with the employee working in a same department? thanks gurus...
To first point that out: I dislike your idea to create such a result listing "pairs" twice and would prefer another, easier query whose results would be better to read. I will come back to this later in this answer.
But anyway, if you really want to produce the outcome you have shown, we can do this with CROSS JOIN. This builds all combinations of employees.
In the WHERE clause, we will set the conditions that they must work in the same department, but have different names:
SELECT
e1.emp_name AS employeeName,
e1.dept_code AS department,
e2.emp_name AS employeeName
FROM
employee e1
CROSS JOIN employee e2
WHERE
e1.dept_code = e2.dept_code
AND e1.emp_name <> e2.emp_name
ORDER BY e1.dept_code, e1.emp_name, e2.emp_name;
To come back to the idea to make this much easier and better to read: We can just use LISTAGG with GROUP BY to produce a comma-separated list of employees per department. I highly recommend to use this approach due to much better performance and readability.
This query will do on new Oracle DB's:
SELECT dept_code,
LISTAGG (emp_name,',') AS employees
FROM employee
GROUP BY dept_code;
On older Oracle DB's, we need to add a WITHIN GROUP clause:
SELECT dept_code,
LISTAGG (emp_name,',')
WITHIN GROUP (ORDER BY emp_name) AS employees
FROM employee
GROUP BY dept_code;
This will produce following result for your sample data:
DEPT_CODE
EMPLOYEES
2
Jim,Kim,Tim
3
Aim,Sim
Here we can try out these things: db<>fiddle
You will get all the pairs (A,B) and (B,A) of employees in the same department at the exclusion of all (A,A) with:
SELECT e1.emp_name AS first_emp_name, e1.dept_code, e2.emp_name AS second_emp_name
FROM employee e1
JOIN employee e2 ON e1.dept_code = e2.dept_code AND e1.emp_name <> e2.emp_name ;

Get count of total employees under each manager (SQL Server)

I need to get, for each of the five people in this table, the total employees reporting to each one of them (either directly or indirectly).
CREATE TABLE employees
([employee] nvarchar(30), [manager] nvarchar(30))
;
INSERT INTO employees
([employee], [manager])
VALUES
('Robert', null),
('Julian', 'Robert'),
('Sophie', 'Robert'),
('Lucy', 'Julian'),
('John', 'Lucy')
;
The output I expect is:
employee
subordinates
Robert
4
Julian
2
Lucy
1
Sophie
0
John
0
I have searched everywhere how to do this type of recursion/hierarchical query, and it seems it is very common to approach this kind of exercise to get the employee hierarchy only (which I managed to do already), but not the total count of employees under each manager.
The best I could get was the following, but it only gets the count for the top manager, while I need it for all employees in the company in a single table (from an answer to this post: SQL Query to get recursive count of employees under each manager).
WITH EmployeeCTE
AS (SELECT e.employee, e.manager as topmanager
FROM employees e, employees m
WHERE e.manager = m.employee AND m.manager IS NULL
UNION ALL
SELECT e.employee, mgr.topmanager
FROM employees e, EmployeeCTE mgr
WHERE e.manager = mgr.employee)
SELECT topmanager, count(*)
FROM EmployeeCTE AS u
GROUP BY topmanager;
Here is a Fiddle to this: http://sqlfiddle.com/#!18/380ba/2
The problem is with getting the zero subordinates for those without subordinates.
One way to get them is via a LEFT JOIN of all employees to the results of the recursive CTE.
WITH CTE_Employees AS (
SELECT employee
FROM employees
GROUP BY employee
)
, RCTE_Managers AS (
SELECT
manager as base_manager
, 1 as depth
, employee
, manager as direct_manager
FROM employees
WHERE manager IS NOT NULL
UNION ALL
SELECT
cte.base_manager
, cte.depth + 1
, emp.employee
, emp.manager
FROM RCTE_Managers cte
JOIN employees emp
ON emp.manager = cte.employee
)
SELECT
emp.employee
, COUNT(DISTINCT mgr.employee) AS subordinates
FROM CTE_Employees emp
LEFT JOIN RCTE_Managers mgr
ON mgr.base_manager = emp.employee
GROUP BY emp.employee
ORDER BY COUNT(mgr.employee) DESC, emp.employee;
employee
subordinates
Robert
4
Julian
2
Lucy
1
John
0
Sophie
0
Test on db<>fiddle here

Returning a column of a table where the value of that column is at least as big as all the rows of that column

I need to return the name of all employees whose years of employment are at least as long as the employment years of all the other employees.
I have the following table
Employees
identification_number first_name employment_years
---------------------------------------------------------
20 Peter 50
21 Edward 37
22 Elizabeth 22
23 Katherine 46
For someone to have at least as many employment years as everybody else, the years of employment column row should should be larger or equal to the others, I therefor tried the following query.
SELECT first_name
FROM Employees E
WHERE NOT EXISTS (SELECT *
FROM Employees E1, Employees E2
WHERE E1.employment_years >= E2.employment_years)
But this gives me no results at all. The result should give me the name Peter, as he has worked the most years in this group of employees. How can I solve this issue?
A simple way uses ALL:
select e.*
from employees e
where e.employment_years >= all (select e2.employment_years
from employees e2
);
You can use not exists as:
select e.*
from employees e
where not exists (select 1
from employees e2
where e2.employment_years > e.employment_years
);

How to mark employees which are also manager

I need to determine whether an employee is any other employee's manager.
Given this table:
Employee Employee's Manager
---------- ------------------
Bob CN=Lisa
Amanda CN=Lisa
James CN=Art
Frank CN=Amanda
Amy CN=Art
I need this:
Employee Employee's Manager Employee IS Manager
---------- ------------------ -------------------
Bob CN=Lisa N
Amanda <-- CN=Lisa Y <--
James CN=Art N
Frank CN=Amanda <-- N
Amy CN=Art N
Because Amanda appears in the "Employee's Manager" column in another employee's row, I need to derive this, adding the additional "Employee IS Manager" field.
I've gotten as far as this (wrong!) subquery for the additional "IS Manager" field, but I do not know how to add it as a column in a subquery:
select
a.* ,
(select 'Y' as IsManager
where exists (select * from Employees b where b.Manager like '%' + #x+ '%' )
)
from Employees a
But I do not know how to make #x refer to Amanda in the Employee column in the other row.
EDIT: I should note that I am not necessarily looking for a "subquery" solution. A JOIN solution, or any other kind of solution is fine for my purposes. Thanks.
You are close but you need a case expression:
select e.* ,
(case when exists (select 1
from Employees m
where m.Manager like '%=' + e.employee_manager
)
then 'Y' else 'N' end
) as isManager
from Employees e;
Note that I tweaked the logic for matching so "Anne" and Roseanne" do not get confused. If the manager always starts with 'CN=', then use like 'CN=' + instead.
You can also use outer apply to get your desired result. Here through outer apply we are getting 'Y' when an employee is also a manager other wise it's returning null. Coalesce() is used to convert null to 'N'.
Schema and insert statements:
create table Employees (Employee varchar(50),employee_Manager varchar(50));
insert into Employees values('Bob', 'CN=Lisa');
insert into Employees values('Amanda', 'CN=Lisa');
insert into Employees values('James', 'CN=Art' );
insert into Employees values('Frank', 'CN=Amanda');
insert into Employees values('Amy', 'CN=Art' );
Query:
select
a.*,coalesce(isManager,'N')[Employee IS Manager]
from Employees a outer apply(select 'Y' from Employees b where b.employee_manager='CN='+a.Employee)manager (isManager)
Output:
Employee
employee_Manager
Employee IS Manager
Bob
CN=Lisa
N
Amanda
CN=Lisa
Y
James
CN=Art
N
Frank
CN=Amanda
N
Amy
CN=Art
N
db<fiddle here

sql query .. confused

I am a newbie and i am not sure how to go about this .. can anybody help me ?
Given the following tables ...
DEPARTMENT
DEPT_ID NAME
1 HR
2 Technical
3 Marketing
4 Sales
EMPLOYEE
ID NAME DEPT_ID SALARY MANAGER_ID
1 Alex 2 2000
2 Sally 1 2000
3 Amit 2 1500 1
4 Jason 1 1500 1
... ... ... ... ...
Using the DEPARTMENT and EMPLOYEE tables from earlier, write a SQL query to print the number of employees working in each department. The output should look something like this:
NAME COUNT
HR 2
Technical 2
Marketing 0
Sales 0
Please note that not all departments have been staffed yet, so some departments may not have any employees. We still want these departments to appear in the results, with a zero count.
Using the EMPLOYEE table from earlier, write a SQL query to print out the number of employees working under each manager. The output should look something like this:
NAME COUNT
Alex 2
Sally 0
You need to join the tables, group by department, and take the count of rows per department.
Try This Link
Solution to the first part of the problem:
select d.NAME, count(e.NAME)
from EMPLOYEE as e
right join DEPARTMENT as d
on e.DEPT_ID = d.DEPT_ID
group by d.DEPT_ID
Solution to the second part of the problem (I'm not sure whether this one is correct or not):
select NAME, count(NAME)
from EMPLOYEE
group by MANAGER_ID
Please check the sqlfiddle: http://sqlfiddle.com/#!2/5e802/13
Try this it may help you :
a)
select d.Name as DepartmentName, count(e.id) as EmployeeCount from employee as e, department as d where e.DEPT_ID = d.DEPT_ID group by d.Name;
b)
select a.name as Manager_Name,Count(a.name) as EmployeeCount from employee a, employee b where a.id=b.MANAGER_ID group by a.name;