Get the minimum employees with a given job - sql

I have this table:
Name Null? Type
-------------------------- -------- ------------
EMPLOYEENO NOT NULL NUMBER(4)
ENAME VARCHAR2(15)
JOB VARCHAR2(15)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER
COMM NUMBER
DEPTNO NUMBER(2).
I want to get the department with minimum employees who have a given job (for example all the employees with 'Analyst' job).
Can you please help me with the query?

Here the key is to get the count of Employee doing particular job in each department. In below query, this is achieved by subquery. Then, we want to get the Department with minimum no. of employee doing that job so we ordered the records returned by subquery in ascending and then select the first result by using rownum = 1
SELECT DEPTNO from (
SELECT COUNT(*) AS NO_OF_EMP , DEPTNO
FROM EMPLOYEE EMP
WHERE EMP.JOBNAME = 'Analyst'
GROUP BY DEPTNO
ORDER BY NO_OF_EMP ASC )
where ROWNUM = 1;

Given that the minimum number of such employees could be 0, you need to be a bit clever about how you do this:
select d.*
from (select deptno,
sum(case when jobname = 'Analyst' then 1 else 0 end) as numAnalysts
from employees
group by deptno
order by numAnalysts asc
) d
where rownum = 1;

Related

Why are these 2 queries giving different outputs?

Query no 1:-
SELECT COUNT(ENAME)
FROM EMP
WHERE
JOB IN 'MANAGER'
OR JOB IN 'ANALYST'
AND SAL IN (
SELECT SAL + NVL (COMM,0)
FROM EMP
WHERE SAL LIKE '%0')
GROUP BY JOB;
The Query 1 gives me the following output:-
COUNT(ENAME)
------------
3
2
Query no 2:-
SELECT COUNT(ENAME)
FROM EMP
WHERE
JOB = ANY (
SELECT JOB
FROM EMP
WHERE JOB IN ('MANAGER', 'ANALYST')
)
AND SAL IN (
SELECT SAL + NVL (COMM,0)
FROM EMP
WHERE SAL LIKE '%0'
)
GROUP BY JOB;
The Query 2 gives me the following output:-
COUNT(ENAME)
------------
2
2
Summary: The AND operator has higher precedence than the OR operator. To fix it, use brackets around the OR expression.
AND has higher precedence than OR so your first query is the equivalent of (with added brackets and indentation to emphasise the precedence):
SELECT COUNT(ENAME)
FROM EMP
WHERE JOB IN 'MANAGER'
OR ( JOB IN 'ANALYST'
AND SAL IN (
SELECT SAL + NVL (COMM,0)
FROM EMP
WHERE SAL LIKE '%0'
)
)
GROUP BY JOB;
So you are finding either: managers with any salary; or analysts whose salary equals the salary plus commission of any other employee.
Your second query is the equivalent of:
SELECT COUNT(ENAME)
FROM EMP
WHERE ( JOB IN 'MANAGER'
OR JOB IN 'ANALYST'
)
AND SAL IN (
SELECT SAL + NVL (COMM,0)
FROM EMP
WHERE SAL LIKE '%0'
)
GROUP BY JOB;
Which finds: any employee who is either a manager or an analyst and whose salary equals the salary plus commission of any other employee.
You could rewrite your first query to:
SELECT COUNT(ENAME)
FROM EMP
WHERE JOB IN ('MANAGER', 'ANALYST')
AND SAL IN (
SELECT SAL + NVL (COMM,0)
FROM EMP
WHERE SAL LIKE '%0'
)
GROUP BY JOB;
JOB IN 'MANAGER' OR ...
means all managers OR the next predicate
please put parentheses to achieve the expected result
JOB IN ('MANAGER', 'ANALYST')

How to get distinct column with max value and limit, hive

I have a table emp with around 10 rows
empno,ename,dept,sal,deptno
now I want result as ename from each dept who as max sal.
EX:
12,ravi,manager,20000,10
43,hari,engineer,10000,20
32,sam,clerk,5000,30
Get the max salary for each dept and then get the ename for each max salary.
select ename,dept,sal
from emp
where sal in (select max(sal) as sal from emp group by dept)
Using row_number() and partition
select * from
(
select ename,dept,sal, row_number() over (partition by dept order by sal desc) as row_no
from emp
) res
where res.row_no = 1

SQL group type of query

I am using SQL Developer and I have this table structure:
Name Null Type
-------------- -------- ------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
DEPARTMENT_ID NUMBER(4)
SALARY NUMBER(8,2)
What I want to do is print out the department_id which has AT LEAST 2 employees with salaries greater than 10000.
I though this would be the query
select department_id
from employees
having count(select * from employees where salary > 10000) > 2
group by department_id;
but, from what I found out, you can't put a SELECT statement inside COUNT so now I an stuck and I don't know how else am I supposed to do this query. Any suggestion is welcome.
UPDATE: Please note that I want AT LEAST 2 employees to have salary > 10000, not all of them
SELECT Department_Id,
COUNT(*)
FROM Employee
WHERE Salary > 10000
GROUP BY Department_Id
HAVING COUNT(*) > 1
SQL Fiddle example.
SELECT department_id FROM employees
WHERE salary > 10000 GROUP BY department_id HAVING COUNT(*) >= 2;

Oracle SQL query issue

I am using oracle's SQL Developer. To begin with, I have this table:
Name Null Type
-------------- -------- ------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
DEPARTMENT_ID NUMBER(4)
I would like to retrieve(select) the ID of the department in which are the most employees.
I managed through a statement to retrieve all the numbers of the employees in every department:
select count(employee_id), department_id
from employees
group by department_id;
It gives me something like:
count(employee_id) | department_id
---------------------|------------------
6 100
16 30
1 12
What I would like to do is ONLY to retrieve the department_id 30, which (in this case) has the most employees.
A typical way to do this in Oracle:
select department_id
from (select count(employee_id), department_id
from employees
group by department_id
order by count(employee_id) desc
) t
where rownum = 1;
If you have potential duplicates and want all the department ids, then a join to the max or analytic function is a better approach. For example:
select department_id
from (select count(employee_id), department_id,
rank() over (order by count(employee_id) desc) as seqnum
from employees
group by department_id
) t
where seqnum = 1;

how to display null value attributes?

This is the question:
Create a query to list all the employees who joined this organization before any clerks
were hired and who earn more than any manager.
This is what I have so far:
select ename
from emp
where hiredate<any(select hiredate from emp
where job='CLERK')
and job!='CLERK'
and sal>any(select sal from emp
where empno=super);
-But one of the employees don't have a supervisor (which is null) so it doesn't show any of the employees.
Something like this?
SELECT ename
FROM emp
WHERE hiredate < ANY (
SELECT hiredate
FROM emp
WHERE job = 'CLERK'
)
AND job <> 'CLERK'
AND sal > ANY (
SELECT sal
FROM emp
WHERE empno IN (
SELECT super
FROM emp
WHERE super IS NOT NULL
)
);
Is it a homework? If yes, should be labelled as such.