Creating a one query list - sql

List a count of the number of employees who work in either department 10 or 20, the average, minimum, and maximum employee salary in these departments, and a total of all their salaries combined (This question must be done by using one query)
MY CODE:
SELECT DEPTNO, AVG(SAL), MAX(SAL), MIN(SAL), SUM(SAL) AS TOTAL_SAL
FROM EMP
WHERE DEPTNO = 10 OR DEPTNO=20
GROUP BY DEPTNO;
Table Schema:

So add a:
count(DEPTNO) as NumberEmployeesInDept
to your select and I think you will be done.

Related

DB2 SQL Having Clause with a Nested Table Expression

Return the department number and the total payroll for the department that has the highest payroll. Payroll is the sum of all salaries and commissions of the department. Use a having clause with a nested table expression.
select e0.deptno,
(select sum(sal+com) FROM emp
group by deptno
having sum(sal+com) >= all(select sum(sal+com)
from emp
group by deptno) )as top
from emp as e0
group by e0.deptno
;
But my result is not correct. Im not so sure if my nested table expression combined with the having clause is done the right way. Can someone, try to help me? Thanks in advance.
As far as concerned, you don't need a having clause for this. You can just aggregate by department, order the results by payroll and fetch the first record:
select deptno, sum(sal + com) payroll
from emp e
group by deptno
order by payroll desc
fetch first 1 rows only
If you do want to use having (or if you are using a version of db2 that does not support the fetch ... rows ... clause), then we can build on your initial idea as follows:
select deptno, sum(sal + com) payroll
from emp
group by deptno
having sum(sal + com) >= all (
select sum(sal + com) from emp group by deptno
)

SQL Server 2014 Management Studio update query

I have a table Employee with those columns
empid, empname, job, hiredate, sal, comm, deptno
I want to verify if this is correct:
Number of employees in each department
How many people there are in each type of job in each department
Display the department and number of employees in department with fewer than 6 employees
Find the employee name and its salary who is earning maximum salary in dept 20
Here is what I have tried:
Query #1:
select DEPTNO, count(*) AS NO_OF_PERSONS
from EMP
group by DEPTNO;
Query #2:
select job, count(*) AS NO_OF_PERSONS
from EMP
group by job;
Query #3:
update EMPLOYEE
set sal = sal + 1000
where com > 2500;
And I am unable to do the 4th part.
I hope that below queries will help you.
no of employees in each dept?
SELECT DEPTNO,
count(*) AS NO_OF_PERSONS
FROM EMP
GROUP BY DEPTNO;
how many people are there in each type of job in each department?
SELECT job,
deptno,
count(*) AS NO_OF_PERSONS
FROM EMP
GROUP BY job,
deptno;
display the department and no of employees in department with fewer than 6 employee.
SELECT deptno,
count(*)
FROM emp
GROUP BY deptno
HAVING count(*) < 6;
find the employee name and its salary who is earning maximum salary in dept 20.
SELECT Max(salary_amount),
empid
FROM EMP
WHERE deptno = 20
GROUP BY empid;
You can start learning Basic SQL here
select e1.name, e1.sal
from EMP e1
where e1.DEPTNO = 20
and not exists(select *
from EMP e2
where e2.DEPTNO = 20
and e2.sal > e1.sal);

How to calculate percentage in column?

I've got a task to calculate smallest salary in the departments and how many percents is it from total salary.
Also i can use only one select statement and probably I need to use window functions.
This is how i started:
SELECT distinct department_id,
min(salary) over(partition by department_id) as min_sal
FROM employees;
But if I use RATIO_TO_REPORT function it show all table, not grouped by department_id.
Sounds like
select min(salary) as min_salary, round( min(salary)/sum(salary) * 100 , 1 ) as percent
from employees
group by department_id
;
If you also need the employee's name who has the least salary in each department (assuming there's always only one), then add
, min(empl_name) keep (dense_rank first order by salary) as min_sal_empl_name
to the SELECT statement. If there can be ties for the least salary, and you need all the employees, please say so - in that case you probably need analytic functions as you guessed. Something like:
select empl_name, salary, round(salary/tot_sal*100, 1) as percent
from ( select empl_name, salary,
sum(salary) over (partition by department_id) as tot_sal,
rank() over (partition by department_id order by salary) as rn
from employees
)
where rn = 1
;
Added: OP indicated they need salary as percentage of total salary (across all departments) after all. This can be done by combining ratio_to_report() with empty windowing condition (no "partition by" anything) with rank() partitioned by department to pick up least salary in each department.
If you don't like over () for the windowing clause in ratio_to_report(), it can also be written as over (partition by null) to make it super-clear no partitioning is intended or needed.
The solution uses the EMP table in the SCOTT schema for testing, since the original post did not include sample data.
select deptno, empno, ename, sal, percent
from (
select empno, ename, sal, deptno,
round(100 * ratio_to_report(sal) over (), 1) as percent,
rank() over (partition by deptno order by sal) as rn
from scott.emp
)
where rn = 1
;
DEPTNO EMPNO ENAME SAL PERCENT
------ ----- ------ ---- -------
10 7934 MILLER 1300 4.5
20 7369 SMITH 800 2.8
30 7900 JAMES 950 3.3

SQL Subquery and joins

There are 2 tables available
EMP(empname PK, empno, sal, comm, deptno, hiredate, job, mgr)
DEPT(depnto, dname, loc)
The queries are
a)Display the ename and dname who is earning the first highest salary
They have given a statement this has to be done using only subqueries and Join
So i started like this:
select A.ename, B.dname from emp A, dept B where A.deptno=B.deptno
and i tried various perm&comb, but i couldn't get the join statement...
This is not a homework problem, i am just trying to solve the exercise problem given in my textbook..Thanks in advance
To get the record with the max salary I've Ordered by e.sal DESC. This will order the records in terms of salary, with the highest at the top (DESC = Descending, and therefore highest-lowest).
Then I've used TOP 1 to only return 1 record.
To get the dname I've joined the tables relating the 2 deptno columns.
SELECT TOP 1 e.empname
,d.dname
FROM [EMP] e
JOIN [DEPT] d ON d.deptno=e.deptno
ORDER BY e.sal DESC
I hope this helps
You can try following query:
SELECT emp.ename,dept.dname FROM emp
JOIN dept ON emp.deptno=dept.deptno
WHERE emp.sal=(SELECT MAX(sal) FROM emp)

Combining columns

I am trying to do the following:
I have a table with ename, job, deptno, and sal. I am trying to initiate a query that returns the top earners of each department. I have done this with grouping and a subquery. However, I also want to display the average sal by deptno. So the following would be the result:
"ename" "dept" "sal" "average of dept"
sal 20 1000 500
kelly 30 2000 800
mika 40 3000 400
this might be impossible since the average does not associate with the other rows.
any suggestion would be appreciated. Thanks. I am using Oracle 10g to run my queries.
You could use analytic functions:
WITH RankedAndAveraged AS (
SELECT
ename,
dept,
sal,
RANK() OVER (PARTITION BY dept ORDER BY sal DESC) AS rnk,
AVG(sal) OVER (PARTITION BY dept) AS "average of dept"
FROM atable
)
SELECT
ename,
dept,
sal,
"average of dept"
FROM RankedAndAveraged
WHERE rnk = 1
This may return more than one employee per department if all of them have the same maximum value of sal. You can replace RANK() with ROW_NUMBER() if you only want one person per department (in which case you could also further extend ORDER BY by specifying additional sorting criteria to pick the top item, otherwise it will be picked randomly from among those with the maximum salary).
This should work. The only trick is that if you have several employees with the maximum salary in a department, it will show all of them.
SELECT t.ename, t.deptno, mx.sal as sal, mx.avg_sal as avg_sal
FROM tbl t,
(SELECT MAX(sal) AS sal, AVG(sal) AS avg_sal, deptno
FROM tbl
GROUP BY deptno) mx
WHERE t.deptno = mx.deptno AND t.sal = mx.sal
Not sure about Oracle, haven't used it in about 10 years, but something like this should be possible:
SELECT
ename, deptno, sal,
(SELECT AVG(T2.sal)
FROM tbl T2
WHERE T2.deptno = T.deptno
) AS average_of_dept
FROM tbl T
GROUP BY deptno
HAVING sal = MAX(sal)