Using ROUND, AVG and COUNT in the same SQL query - sql

I need to write a query where I need to first count the people working in a department, then calculate the average people working in a department and finally round it to only one decimal place. I tried so many different variations.
That's what I got so far although it's not the first one I tried but I always get the same error message. (ORA-00979 - not a group by expression)
SELECT department_id,
ROUND(AVG(c.cnumber),1)
FROM employees c
WHERE c.cnumber =
(SELECT COUNT(c.employee_id)
FROM employees c)
GROUP BY department_id;
I really don't know what do to at this point and would appreciate any help.
Employees Table:

Try this (Oracle syntax) example from your description:
with department_count as (
SELECT department_id, COUNT(c.employee_id) as employee_count
FROM employees c
group by department_id
)
SELECT department_id,
ROUND(AVG(c.employee_count),1)
FROM department_count c
GROUP BY department_id;
But this query not make sense. Count is integer, and count return one number for one department in this case AVG return the same value as count.
Maybe you have calculate number of employee and averange of salary on department?

Related

Misuse of aggregate function AVG() in SQL

I have an Employees table which looks like this:
employee_id employee_name employee_salary
1 Tom 35000
2 Sarah 50000
3 David 45000
4 Rosie 55000
5 Michael 45000
I need to return the employees salary that is higher than the average salary but the below command is having an error saying '1 misuse of aggregate function AVG()'.
SELECT employee_salary
FROM Employees
WHERE employee_salary > AVG(employee_salary);
The output that I'm expecting to get is:
employee_id employee_name employee_salary
2 Sarah 50000
4 Rosie 55000
Please advise, thank you!
I need to write the SQL query to return the number of employees for each department.
I assume you're looking for something like this:
SELECT department_id
,COUNT(employee_id) AS TotalEmployees
FROM Department
LEFT JOIN Employees
ON Employees.department_id = Department.department_id
GROUP BY department_id
Also, I need to return the employees salary that is higher than the average salary
The simplest way to return the salaries that are higher than average as a beginner sql programmer is probably something like this:
SELECT employee_salary
FROM Employees
WHERE employee_salary > (SELECT AVG(employee_salary)
FROM Employees)
As the others said, the other questions just require a bit of research. There are tonnes of resources out there to learn, but it takes time...
I need to write the SQL query to return the number of employees for each
department. However, my below command is not correct:
This is not what you ask for.
You get the join correct, but you ask for:
SELECT COUNT(Employees.employment_id)
The count how often different employment id's exist - which is 1 for an employee in one department, or X with X being the number of entries in the join. As the department_id entry is part of the employee table, this CAN NOT HAPPEN. TOTALLY not asking what you want.
I'm using the LEFT JOIN here because I am returning the result from the
Employees table is this right?
Depends - a normal join should work here. Left is only sensible if the other side can be empty - which I would assume is not possible (there are no rows with Employees.department_id being NULL).
You you want is a count (without anything in the brackets) and a group by department_id. And obviously the department id:
SELECT Department.department_id, count() FROM....
Furthermore, are there any tips to speed up SQL Server's performance?
Just pointing you to https://use-the-index-luke.com/ - indices are a cornerstone for any decent performance.
Ignoring your second question - one per question please.

SQL query from Lynda.com

I have a question about two queries. Will these two queries give the same result? I am trying to find the average salary by department:
Select s1.department, avg(s1.salary)
From
(Select department, salary
From staff
Where salary > 100000) s1
Group by s1.department
vs
select department, avg(salary) as avg_salary
from staff
where salary > 100000
group by department
Yes, it gives the same amounts back.
the bottom query gets data from a sub select which gets its data from the table, whereas the top query gets it straight from the table itself.
There are no additional filters in there. So the result will be the same.
you can test it out however, don't take my word for it.

Oracle 11g: Write a query that lists the highest earners for each department

This is a problem I've spent hours on now, and tried various different ways. It HAS to use Subqueries.
"Write a query that lists the highest earners for each department. Include the last_name, department_id, and the salary for each employee."
I've done a ton of subquery methods, and nothing works. I either get an error, or "No rows return". I'm assuming because one of the department_id is null, but even with NVL(department_id), I'm still having trouble. I tried splitting the table, and had no luck. Textbook's no help, my instructor is kind of useless, please... any help at all.
Here's a snapshot of the values, if that helps.
https://www.dropbox.com/s/bxtntlzqixdizzp/helpme.png?dl=0
You can rank the values within each department - then pull only the first place ranks in the outer query.
select a.last_name
,a.department_id
,a.salary
from (
select last_name
,department_id
,salary
,rank() over (partition by department_id order by salary desc) as rnk
from tablename
) a
where rnk=1
The partition groups all employees together who share the same department and should work regardless of the null value.
After grouping them - the order by tells that group to order on salary descending, and give a rank. You can run just the inner query to get an idea of what it does.

Using aggregate function for seprate rows

There is a table with name jobs where for different department number salary is giving. Same department can have more than one job so the salary may vary. Now i want to solve this query:
"Find the average salaries for each department without displaying the respective department numbers."
Here i should use avg but how to use it so that i can get my result of each department no separately?
I think what you're looking for is the GROUP BY clause. If I understand your question correctly then something like this should do the trick.
SELECT AVG(salary) FROM table_name GROUP BY department

How to calculate Standard Deviation in Oracle SQL Developer?

I have a table employees,
CREATE TABLE employees (
employeeid NUMERIC(9) NOT NULL,
firstname VARCHAR(10),
lastname VARCHAR(20),
deptcode CHAR(5),
salary NUMERIC(9, 2),
PRIMARY KEY(employeeid)
);
and I want to calculate Standard Deviation for salary.
This is the code I am using:
select avg(salary) as mean
,sqrt(sum((salary-avg(salary))*(salary-avg(salary)))/count(employeeid)) as SD
from employees
group by employeeid;
I am getting this error:
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:
Error at Line: 260 Column: 12
Line 260 Column 12 is avg(salary)
How can I sort this out?
Oracle has a built-in function to calculate standard deviation: STDDEV.
The usage is as you'd expect for any aggregate function.
select stddev(salary)
from employees;
I'd just use the stddev function
SELECT avg(salary) as mean,
stddev(salary) as sd
FROM employees
It doesn't make sense to group by employeeid since that is, presumably unique. It doesn't make sense to talk about the average salary by employee, you want the average salary across all employees (or all departments or some other aggregatable unit)
The salary-avg(salary) can't be evaluated; avg(salary) is not available during execution of the query but only after all records are retrieved.
I would suggest to add AVG calculations in a subquery and JOIN it to the main one
select avg(salary) as mean,
sqrt(sum((salary-avg_res.avg)*(salary-avg_res.avg))/count(employeeid)) as SD
from employees JOIN
(select employeeid,avg(salary) as avg
from employees
group by employeeid) avg_res ON employees.employeeid=avg_res.employeeid
group by employeeid;
I thought you had to include the column in the GROUP BY in the SELECT:
select employeeid
,avg(salary) as mean
,sqrt(sum((salary-avg(salary))*(salary-avg(salary)))/count(employeeid)) as SD
from employees
group by employeeid;
But on further reflection the query doesn't make much sense unless it's historical data. An employee id ought to be unique to a single employee. Unless this is an average over time there should be only one salary per employee. Your mean will be the salary and the standard deviation will be zero.
A better query might be average of all salaries. In that case, remove the GROUP BY.
One more nitpick: the formula you're using is more properly called the population standard deviation. The sample deviation divides by (n-1).