how get company wise highest salaried employee name from this schema - sql

the database schema is like this:
employee(emp_id#,person_name,dob,street,city)
company(company_id#, company_name,city)
works(emp_id,company_id,salary)
manages(emp_id,manager_id)
insert into employee values('e-1','dipankar pal','15-jul-1997','h.m raod','kolkata');
insert into employee values('e-2','subhadip roy','15-jan-1997','garia','kolkata');
the manages table may be little bit confusing, here are some data I've inserted to clear my point
insert into manages values('e-3','e-1');
insert into manages values('e-4','e-1');
insert into manages values('e-5','e-1');
insert into manages values('e-6','e-2');
insert into manages values('e-7','e-2');

Try
SELECT Z.COMPANY_NAME, E.PERSON_NAME, Z.HIGHEST_SALARY
FROM
(SELECT C.COMPANY_ID, C.COMPANY_NAME, MAX(W.SALARY) AS HIGHEST_SALARY
FROM
WORKS W INNER JOIN COMPANY C
ON W.COMPANY_ID = C.COMPANY_ID
GROUP BY C.COMPANY_ID, C.COMPANY_NAME ) Z
INNER JOIN WORKS W
ON Z.COMPANY_ID = W.COMPANY_ID
AND Z.HIGHEST_SALARY = W.SALARY
INNER JOIN EMPLOYEE E
ON W.EMP_ID = E.EMP_ID
ORDER BY Z.HIGHEST_SALARY DESC;

select company.company_name,employee.person_name as employee_name,y.salary as salary from employee,company,
(select works.emp_id,works.company_id,works.salary from works,
(select company_id,max(salary) as high from works group by(company_id)
)x where high=works.salary) y
where employee.emp_id=y.emp_id and company.company_id=y.company_id order by company_name
;

Related

List the surnames of bosses who manage at least two employees from the query below

I need to get the surnames of bosses who manage at least two employees from the query below that earn no more than twice the average earnings of ALL people they direct.
I'm stuck here:
SELECT surname from emp k INNER JOIN
(SELECT surname, base_salary
from emp p LEFT JOIN
(select id_team, avg(base_salary) as s, count(*) as c from emp group by id_team)
as o ON(p.id_team = o.id_team)
where p.base_salary between o.s*0.7 and o.s*1.3 and o.c >=2) l ON (k.id_boss = o.id_boss)
having count(k.id_boss) >2 ??? AND k.base_salary < ????
I hope you get my point. Any advices how could I do that?
Here's what the full table looks like:
Based on your query you should just add the proper having clause
having count(k.id_boss) >2 AND k.base_salary < 2*l.s
SELECT k.surname
from emp k
INNER JOIN (
SELECT surname, base_salary, id_boss
from emp p
LEFT JOIN (
select id_team, avg(base_salary) as s, count(*) as c
from emp
group by id_team
) o ON p.id_team = o.id_team
where p.base_salary between o.s*0.7 and o.s*1.3 and o.c >=2
) l ON k.id_boss = o.id_boss
group by k.surname
having count(l.id_boss) >2
AND k.base_salary < 2*l.s

Query to get employee of different departments

I have 3 tables: Employee, Department and employeeProject.
The relation between employee and employeeproject is one-to-many. The relation between employee and department is many-to-one.
I want to write a query to select 10 employees who have worked in projects 3 and 4. The query should return employees of different departments if possible.
The query below kind of works. The only problem is that the relationship between employee and employeeproject is one-to-many, so it might return the same employee number multiple times.
I cannot use distinct because all fields in the order by clause should be used in select when using distinct.
select top 10 empid from employee e
inner join department d on d.depId=e.depid
inner join employeeProject p on p.empid=e.empid
where p.projectID in (3,4)
order by row_number() over(partition by e.depId order by e.empid)
Bit of a guess, but use an EXISTS?
SELECT TOP 10 e.empid
FROM employee e
JOIN department d ON e.depid = d.depid
WHERE EXISTS (SELECT 1
FROM employeeproject p
WHERE p.emdid = e.empid
AND p.projectid IN (3,4))
ORDER BY e.depid, e.empid;
I suggest aggregating by employee, and then using an assertion the HAVING clause:
SELECT TOP 10 e.empid
FROM employee e
INNER JOIN department d
ON d.depId = e.depid
INNER JOIN employeeProject p
ON p.empid = e.empid
WHERE
p.projectID IN (3,4)
GROUP BY
e.empid
HAVING
MIN(p.projectID) <> MAX(p.projectID);
If the minimum and maximum projectID are not equal for a given employee, after restricting to only projects 3 and 4, then it implies that this employee meets the criteria.
Why not just use select distinct?
select distinct top 10 empid
from employee e inner join
employeeProject p
on p.empid = e.empid
where p.projectID in (3, 4)
order by row_number() over (partition by e.depId order by e.empid);
Note that the department table is not needed.
Alternatively,
select top (10) e.*
from employee e
where exists (select 1
from employeeprojects ep
where p.emdid = e.empid and
p.projectid in (3, 4)
)
order by row_number() over (partition by e.depid order by newid());

Missing expression problem in SQL using Oracle

I want to get the number of employees by department and I wrote this script using Oracle but it always says that there is a missing expression
The columns used in my tables :
department :name (the name of the department) -
depnum (the id of the department"primary key"),
employee : empnum (the id of the employee) -
depnum (the id of the department in which the employee in question is working "foreign key")
Query:
select
s.name
from
department s
inner join
employee p on s.depnum = p.depnum
group by
s.name
having
count(p.empnum) = max(select count(p.empnum)
from employee p, department s
where s.depnum = p.depnum
group by s.name) ;
If you want the number of employees by department, I would expect something like this:
select s.name, count(*) as num_employees
from department s inner join
employe p
on s.depnum = p.depnum
group by s.name ;
If you want the department names with the maximum number of names, you can use a having clause:
select s.name, count(*) as num_employees
from department s inner join
employe p
on s.depnum = p.depnum
group by s.name
having count(*) = (select max(cnt)
from (select count(*) as cnt
from employee e2
group by e2.depnum
) e2
);
The problem with your query is that you are attempting to take the max() of a subquery. That syntax is not allowed -- and not necessary.
you sql statement is not correct that's why it thrown that error. I think you tried something like below
select s.name
from department s
inner join employe p on s.depnum=p.depnum
group by s.name
having count(p.empnum)=
select max(cnt) from
(
select count(p.empnum) as cnt
from employe p join department s
on s.depnum=p.depnum
group by s.name
) t;

SQL employees working for contractors

Hello I have a database and i need to answer a question whether some employee works for multiple contractors. I believe that all this info is in one table.
contract (contractor_no FK ,emp_no FK, job_no FK, is_active)
other tables that might be involved
cont_employee (emp_no PK, emp_fname, emp_lname, birth_date)
contractor (contractor_no PK, contractor_name)
Group by the employee and select only those having more than one record
select e.emp_no, e.emp_fname, e.emp_lname
from cont_employee e
join contract c on e.emp_no = c.emp_no
where c.is_active = 1
group by e.emp_no, e.emp_fname, e.emp_lname
having count(distinct c.contractor_no) > 1
above query using group by on varchar column and also using distinct .
you can try row_number.
like this,
SELECT * FROM
(
select e.emp_no, e.emp_fname, e.emp_lname
,ROW_NUMBER()OVER(PARTITION BY emp_no
ORDER BY contractor_no) ROWNUM
from cont_employee e
join contract c on e.emp_no = c.emp_no
where c.is_active = 1
)T4
WHERE ROWNUM>1

SQL: Have 4 Tables, Looking to find unmatched data

I've always done this back asswards in PHP or ASAP, so I figure it's time to actually learn the proper way to do it in SQL. I have the following 4 tables in a database:
Category (Fields: CategoryNumber, Desc) (small table with 15 rows)
Media (Fields: MediaID, Desc, CategoryNumber, etc) (huge table with 15,000 rows)
Sales (Fields: Date, MediaID, EmployeeID etc) (huge table with 100,000 rows)
Employees (Fields: EmployeeID, Name, etc) (small table with only 20 rows)
Category only links to Media
Media has links to both Category and Sales.
Sales links to both the Media and Employee
Employee only links to Sales
What I would like to do is to write a query which tells me what categories a given employee has never sold any media in.
I can write a simple query that looks for unmatched data between 2 tables, but I have no clue how to do it when I'm dealing with 4 tables.
Thanks for your time and help!
Here's my suggestion:
select *
from Category c
where not exists (
select *
from Employee e
inner join Sales s on s.EmployeeId = e.EmployeeId
inner join Media m on m.MediaID = s.MediaID
where e.Name = 'Ryan' and m.CategoryNumber = c.CategoryNumber
)
To query all employes with the categories in which they didn't sell anything:
select e.EmployeeName, c.CategoryNumber
from Category c
cross join Employee e
where not exists (
select *
from Sales s
inner join Media m on m.MediaID = s.MediaID
where c.categoryNumber = m.CategoryNumber
and s.EmployeeId = e.EmployeeId
)
SELECT c.CategoryNumber, c.Desc
FROM Category c
WHERE NOT EXISTS
(
SELECT *
FROM Employees e
INNER JOIN Sales s on s.EmployeeID = e.EmployeeID
INNER JOIN Media m on m.MediaID = s.MediaID
WHERE e.Name = "Ryan"
AND m.CategoryNumber = c.CategoryNumber
)
MS Access evidently needs a lot of parentheses (thanks, Ryan!):
select *
from Category c
where not exists
( select *
from ( Employee e
inner join Sales s on (s.EmployeeId = e.EmployeeId))
inner join Media m on (m.MediaID = s.MediaID)
where (e.Name = 'Ryan' and m.CategoryNumber = c.CategoryNumber) )
select c.desc
from category
left outer join (select s.employeeid,m.categorynumber
from sales s
inner join media m on s.mediaid=m.mediaid
inner join employee e on e.employeeid=s.employeeid
where e.name = 'JOE'
group by employeeid,categorynumber) t on t.categorynumber=c.categorynumber
where s.employeeid is null
Modified Answer based on the solution provided by Carl in Access SQL Syntax:
select *
from Category c
where not exists (
select *
from (Employee e
inner join Sales s on (s.EmployeeId = e.EmployeeId))
inner join Media m on (m.MediaID = s.MediaID)
where (e.Name = 'Ryan' and m.CategoryNumber = c.CategoryNumber)
)