Missing Function Error in Count - oracle

I have 2 data tables, Employees and Departments. I want to show the department numbers, department names, the number of employees in each department, the average salary of each department, the employee names, their salaries, and jobs IDs of the employees. Here's what I wrote for my code:
select d.department_id, d.department_name, e.count(*) Employees,
avg(e.salary) Avg_salary, e.last_name, e.salary, e.job_id
from departments d join employees e
on d.department_id = e.department_id
group by d.department_id, d.department_name, e.last_name, e.salary, e.job_id
order by d.department_id;
However, the error "Missing Function" appears when I run the code. How do I fix it?

try this:
SELECT d.department_id,
d.department_name,
Count(*) Employees,
Avg(e.salary) Avg_salary,
e.last_name,
e.salary,
e.job_id
FROM departments d
JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_id,
d.department_name,
e.last_name,
e.salary,
e.job_id
ORDER BY d.department_id;

e.count(*) should just be count(*).
EDIT:
Is this what you need?
COUNT(*) OVER (PARTITION BY e.department_id) DeptCt

Related

Oracle HR Schema. Selecting of max salary from Employees

I need to select city, max salary in the city and employee name whose salary is max from Oracle HR Schema.
I try to do below code, but city name repeats:
select l.city, e.last_name, e.salary from locations l
inner join departments d on l.location_id = d.location_id
inner join employees e on d.department_id = e.department_id
and e.salary = (select max(salary) from employees where department_id = d.department_id)
group by l.city, e.last_name, e.salary
order by e.salary;
What is wrong with my code?
I've attached result, which I need.Correct SQL result
You can use the DENSE_RANK analytic function (which will return all employees with the maximum salary per city):
SELECT city,
last_name,
salary
FROM (
SELECT l.city,
e.last_name,
e.salary,
DENSE_RANK() OVER (
PARTITION BY l.location_id
ORDER BY e.salary DESC
) AS rnk
FROM locations l
INNER JOIN departments d
ON l.location_id = d.location_id
INNER JOIN employees e
ON d.department_id = e.department_id
)
WHERE rnk = 1;
or aggregation with KEEP (which will only return one employee with the maximum salary and the maximum last name per location):
SELECT MAX(l.city) AS city,
MAX(e.last_name) KEEP ( DENSE_RANK LAST ORDER BY e.salary ) AS last_name,
MAX(e.salary) AS salary
FROM locations l
INNER JOIN departments d
ON l.location_id = d.location_id
INNER JOIN employees e
ON d.department_id = e.department_id
GROUP BY
l.location_id
What is wrong with my code?
You are correlating on department_id = d.department_id and not on the location (or city name; however, don't aggregate on the city name as there could be two different locations with the same name).

How to show count from another table?

I'm new to Oracle.
Now, I want to show number of employees working in each department,
and number of employees in each department must be less than 2.
But I only show department_id and department_name
I don't know how to show count.
SELECT d.DEPARTMENT_ID, d.DEPARTMENT_NAME
FROM DEPARTMENTS d
WHERE 2 > (SELECT COUNT(e.EMPLOYEE_ID)
FROM EMPLOYEES e
WHERE d.DEPARTMENT_ID = e.DEPARTMENT_ID);
My output:
DEPARTMENT_ID | DEPARTMENT_NAME
... | ...
Correct output:
DEPARTMENT_ID | DEPARTMENT_NAME | COUNT(EMPLOYYE_ID) |
... | ... | ... |
try this (added correction for handling cases of departments without employees)
SELECT d.DEPARTMENT_ID, d.DEPARTMENT_NAME, NVL(e2.cnt,0) count
FROM DEPARTMENTS d
LEFT JOIN (select e.department_id, count(*) cnt from employees e group by e.department_id) e2
ON d.department_id=e2.department_id
where e2.cnt <2
Or, more compact
SELECT d.DEPARTMENT_ID, d.DEPARTMENT_NAME, count(e2.employee_id)
FROM DEPARTMENTS d
LEFT JOIN employees e ON d.department_id=e.department_id
GROUP BY d.DEPARTMENT_ID, d.DEPARTMENT_NAME
HAVING COUNT(*) <2

Oracle SQL - Subquery to get the employees that receive more than the Max_Salary for their Job_Id

In HR Schema, we have a table jobs, with min and max salary for each job id. I have to find the employees that receive more than the Max_Salary for their Job_Id, using subquery.
I have tried to make this subquery, but I'm getting "no data found".
SELECT FIRST_NAME,SALARY, JOB_ID FROM HR.EMPLOYEES E WHERE SALARY >(SELECT MAX_SALARY FROM HR.JOBS J WHERE E.JOB_ID = J.JOB_ID );
Thanks in advance.
WITH SALARY_DETAIL AS (SELECT JOB_ID, MAX(MAX_SALARY) AS MAX_SALARY FROM JOBS J GROUP BY J.JOB_ID)
SELECT E.FIRST_NAME, E.SALARY, E.JOB_ID FROM HR.EMPLOYEES E , SALARY_DETAIL S
WHERE S.JOB_ID = E.JOB_ID
AND E.SALARY > S.MAX_SALAR

How to use group function in self join?

I want to convert Subquery into Join, following is the subquery
SELECT employee_id, last_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary)
FROM employees);
I wrote following join, but I am getting "ORA-00934: group function is not allowed here" error
SELECT e.employee_id,
e.last_name,
e.salary
FROM employees e
INNER JOIN employees average
ON(e.salary>AVG(average.salary));
You can use this like
SELECT e.employee_id,
e.last_name,
e.salary
FROM employees e
INNER JOIN (select AVG(salary) salary from employees ) average
ON (e.salary > average.salary)
Group by e.employee_id;

Oracle PL/SQL group by issue

I want to do this excercise for Oracle 10g Express
"Write an SQL query to retrieve the department name, firstname,
lastname, salary of the employee who earns the maximum salary for that
department."
I tried this code but it is not working for me.
There are two tables named employees, departments
ERROR is: ORA-00979: not a GROUP BY expression
SELECT first_name, last_name, departments.department_name, salary
FROM employees, departments
where employees.department_id = departments.department_id
group by salary
Output must be like that.
You will want to use an aggregate function to get the result. In this case you will use max() to get the highest salary for each department.
There are several ways that this can be written.
You can use a subquery in a join:
select d.department_name,
e.first_name,
e.last_name,
e.salary
from employees e
inner join
(
select max(salary) MaxSalary, department_id
from employees
group by department_id
) e1
on e.department_id = e1.department_id
and e.salary = e1.maxsalary
inner join departments d
on e.department_id = d.department_id;
Since you are using Oracle, you can use windowing functions to get the result:
select department_name, first_name, last_name, salary
from
(
select d.department_name,
e.first_name,
e.last_name,
e.salary,
row_number() over(partition by d.department_id order by e.salary desc) rn
from employees e
inner join departments d
on e.department_id = d.department_id
) d
where rn = 1
Or you can even use a WHERE clause to filter the data:
select d.department_name,
e.first_name,
e.last_name,
e.salary
from employees e
inner join departments d
on e.department_id = d.department_id
where salary in (select max(salary)
from employees e1
where e.department_id = e1.department_id
group by department_id)
I understand the question that you are asking is in reference to using GROUP BY but I would take a closer look at the question.
"Write an SQL query to retrieve the department name, firstname, lastname, salary of the employee who earns the maximum salary for that department."
I think you would also benefit from looking at the Maximum function since you are looking for the employee with the Maximum salary.
You need an aggregate function to be able to use GROUP BY. Aggregate functions are functions that perform a task over several records. These are functions like SUM, AVG, and COUNT. When you have an aggregate function, you group by whatever is not in the function.
In your example, MAX would be your aggregate function and you can use your GROUP BY successfully.
Here is a link for Aggregate Functions

Resources