Counting the Maximum Number of Values - oracle

I have a data table Employees, I want to show all the employees who have been hired on the same day on which the maximum number of employees has been hired. Here's my code:
select last_name, hire_date, count(*) as "Number of Employees Hired"
from employees
group by last_name, hire_date
where hire_date = max(count(*));
However, this code shows "SQL Command Not Properly Ended" error when I run it. How do I fix it so that it runs correctly?

This may not be the cleanest way, but I think will do the trick:
SELECT last_name,
max_hire.hire_date,
max_hire.cnt
FROM
(SELECT *
FROM
(SELECT hire_date,
COUNT(*) cnt
FROM employees
GROUP BY hire_date
ORDER BY COUNT(*) DESC
)
WHERE rownum = 1
) max_hire
INNER JOIN employees
ON employees.hire_date = max_hire.hire_date

Firstly, you should use WHERE before the GROUP BY clause and secondly you should use the aggregate function (count) correctly, as in your case count(*) cannot be compared within the WHERE clause.
You can go with the approach below without using where: (Tested under MySQL)
select last_name, hire_date, count(*) as "Number of Employees Hired"
from employees
group by last_name, hire_date
Order by "Number of Employees Hired" desc limit 1
Hope this helps. Cheers.

Related

Finding list of max average salary, department wise, whilst displaying both max average salary and department_id

When I try it without displaying department_id it works fine as :
SQL> SELECT MAX(AVG(SALARY)) FROM EMPLOYEE GROUP BY DEPARTMENT_ID;
MAX(AVG(SALARY))
----------------
800000
But when I want to display the department_id's too, it gives me error as follows:
SQL> SELECT DEPARTMENT_ID, MAX(AVG(SALARY)) FROM EMPLOYEE GROUP BY DEPARTMENT_ID;
SELECT DEPARTMENT_ID, MAX(AVG(SALARY)) FROM EMPLOYEE GROUP BY DEPARTMENT_ID
*
ERROR at line 1:
ORA-00937: not a single-group group function
Is there any explanation for this? What am I doing wrong? I went through answers of previous questions like this and tried their solutions but got same or some other error. Any help would be appreciated.
I suggest you use
SELECT department_id, avg_salary
FROM ( SELECT DEPARTMENT_ID,
AVG (SALARY) avg_salary,
RANK () OVER (ORDER BY AVG (salary) DESC) rnk
FROM EMPLOYEE
GROUP BY DEPARTMENT_ID)
WHERE rnk = 1;
i.e.
use your first query as a "source"
additionally, rank average salaries in descending order (using the rank analytic function)
select row which ranks as highest

In case second highest value is missing then use the highest value of salary from employee table

I have an employee table as below. As you can see that second highest salary is 200
Incase the second highest salary is missing then there will be only one row as shown at last . In this case the query should fetch only 100
I have written query as but it is not working. Please help! Thanks
select salary "SecondHighestSalary" from(
(select id,salary,rank() over(order by salary desc) rnk
from employee2)
)a
where (rnk) in coalesce(2,1)
I have also tried the following but it is fetching 2 rows but i need only 1
It sounds like you'd want something like
with ranked_emp as (
select e.*,
rank() over (order by e.sal desc) rnk,
count(*) over () cnt
from employee2 e
)
select salary "SecondHighestSalary"
from ranked_emp
where (rnk = 2 and cnt > 1)
or (rnk = 1 and cnt = 1)
Note that I'm still using rank since you're using that in your approach and you don't specify how you want to handle ties. If there are two employees with the same top salary, rank will assign both a rnk of 1 and no employee would have a rnk of 2 so the query wouldn't return any data. dense_rank would ensure that there was at least one employee with a rnk of 2 if there were employees with at least 2 different salaries. If there are two employees with the same top salary, row_number would arbitrarily assign one the rnk of 2. The query I posted isn't trying to handle those duplicate situations because you haven't outlined exactly how you'd want it to behave in each instance.
If you are in Oracle 12.2 or higher, you can try:
select distinct id,
nvl
(
nth_value(salary, 2) from first
over(partition by id
order by salary desc
range between unbounded preceding and unbounded
following),
salary
) second_max_salary
from employee2

Find second highest salary in each department using rank/dense_rank in hive

These were the two questions asked to me during an interview but only condition is to use rank/dense_rank.
Find second highest salary in each department using rank/dense_rank in
hive.
When there are sufficient records in each department.
When there is only 1 record in few departments.
Guide me if this is even valid or not.
If yes then what should be the queries for the same.
If you need to select all second salary employees then use
dense_rank() over(partition by department order by salary desc) = 2 filter. It will return all employees with second salary.
When there is only 1 record in the department (no second salary exists, one employee in the department), it will be ranked 1 and you will get no records for that department filtering by dense_rank = 2.
If you need to select only one record (not all employees) with second salary then row_number() over(partition by department order by salary desc) = 2 will work, but it will pick one random employee with second salary if there are many employees with second salary. Only one record will be marked with row_number = 2.
Try this:
WITH RESULT AS
(
SELECT salary, DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS SecondHighest FROM Employee
)
SELECT IFNULL(( SELECT salary FROM RESULT WHERE SecondHighest = 2 ORDER BY salary) , NULL) as SecondHighestSalary

Oracle SQL join query to find highest salary

So I have two tables salary and emp whose definition is shown as below
[
I am tring to create a query that Find the employee who draws the maximum salary and Display the employee details along with the nationality.
I created this query
select empcode,
max(basic) as "Highest Sal"
from salary
join emp on empcode;
Please help with this
Your query uses a simple aggregate max(basic) which would find the highest salary. Except you need to join to the EMP table to display other details. This means you can't use aggregation, because we need to GROUP BY the non-aggregated columns, which would make a nonsense of the query.
Fortunately we can solve the problem with an analytic function. The subquery selects all the relevant information and ranks each employee by salary, with a rank of 1 being the highest paid. We use rank() here because that will handle ties: two employees with the same basic will be in the same rank.
select empcode
, empname
, nationality
, "Highest Sal"
from (
select emp.empcode
, emp.empname
, emp.nationality
, salary.basic as "Highest Sal"
, rank() over (order by salary.basic desc ) as rnk
from salary join emp on emp.empcode = salary.empcode
)
where rnk = 1;
Find the employee who draws the maximum salary
An employee can have multiple salaries in your datamodel. An employee's (total) salary hence is the sum of these. You want to find the maximum salary per employee and show the employee(s) earning that much.
You can use MAX OVER to find the maximum sum:
select e.*, s.total_salary
from emp e
join
(
select
empcode,
sum(basic) as total_salary,
max(sum(basic)) over () as max_total_salary
from salary
) s on s.empcode = e.empcode and s.total_salary = s.max_total_salary
order by e.empcode;
Try this:
SELECT * FROM
(SELECT E.EmpCode, E.EmpName, E.DOB, E.DOJ, E.DeptCode, E.DesgCode, E.PhNo,
E.Qualification, E.Nationality, S.Basic, S.HRA, S.TA, S.UTA, S.OTRate
FROM EMP AS E JOIN SALARY AS S ON (E.EmpCode = S.EmpCode) order by S.Basic desc)
WHERE rownum = 1

Difference between not exists and not in

Please somebody explain why
select count(*) from employees where employee_id not in (select manager_id from employees)
returns 0
when clearly there are some employees who are managers also.
I am using HR schema.
based on the query i would suggest you to use
NOT EXISTS as it gives BOOLEAN result which boosts up the performance.
SELECT COUNT(*)
FROM employees
WHERE NOT EXISTS
(SELECT employee_id
FROM employees
WHERE type = 'manager' -- or however you differentiate
-- employees and managers
);
Based on this it looks like you're trying to link the employee_id with the manager_id, which are probably different.
Instead you could query for matching employee_id values for managers, using some other criteria to identify managers in the employees table.
SELECT COUNT(*)
FROM employees
WHERE employee_id NOT IN
(
SELECT employee_id
FROM employees
WHERE type = 'manager' -- or however you differentiate
-- employees and managers
)

Resources