how to write SQL to display How many employees doesn't belong to any department?
How about this?
select count(*)
from employees
where deptno is null;
That's basic filtering:
select count(*) cnt
from employees
where depno is null
That gives you the count of employees that are not assigned to a department. If you want to list the corresponding rows:
select *
from employees
where depno is null
Related
I'm trying to count the number of Departments in a database where there are exaclty 6 employees in each Department.
I've written the query below, but it returns the rows with the Departments where there are 6 employees.
But what I'd like is the TOTAL NUMBER of ROWS where each Department has 6 employees.
Does anyone know how I can modify this query to give me a total number, please?
TIA
select count(Department)
--Department as [Department Name]
from HumanResources.vEmployeeDepartment
GROUP BY Department
HAVING count(Department) = 6
You can wrap your query with another count statement to count the number of departments returned by the inner query:
select COUNT(*) from
(
select Department as cnt
from HumanResources.vEmployeeDepartment
GROUP BY Department
HAVING count(Department) = 6
) as t
employee table
empid(integer)
emp_name(varchar)
salary(integer)
location(varchar)
display employees who have same salary.
how to solve this?
You can use the below query to get the results:
Since you need same salary hence i have grouped out the result with respect to salary and then used a listagg function to retrieve all the employee names with a delimiter.
select salary,listagg(emp_name,' | ') within group (order by emp_name) "Employees"
from employee
group by salary;
Select * from employee where salary is not null
I am new to Sql query if I had a table called Employee:
Id, Name, Department
1 tim sales
2 tom sales
3 jay HR
4 ben design
5 lin design
I am trying to write a query that returns the number of employees in each department.
SELECT COUNT(Department) FROM Employee
Does anyone have any advise on how I can improve this query?
****Edit
What about if I wanted to return the number of employees in the same department
SELECT COUNT(id), department FROM Employee GROUP BY department;
Using group by
SELECT COUNT(id), department FROM Employee GROUP BY department
OR
By WHERE conditionSELECT COUNT(id),Department FROM Employee WHERE Department='HR'
SELECT COUNT([id]), [department] FROM [Employee], GROUP BY [department].
I can get the count of employees and avg salary but when I try to get the the addition select of listing the number of employees paid below the average it fails.
select count(employee_id),avg(salary)
from employees
Where salary < avg(salary);
select count(*), (select avg(salary) from employees)
from employees
where salary < (select avg(salary) from employees);
The problem is that AVG is an aggregation function. SQL is not smart enough to figure out how to mix aggregated results within the rows. The traditional way is to use a join:
select count(*), avg(e.salary),
sum(case when e.salary < const.AvgSalary then 1 else 0 end) as NumBelowAverage
from employees e cross join
(select avg(salary) as AvgSalary from employees) as const
select TotalNumberOfEmployees,
AverageSalary,
count(e.employee_id) NumberOfEmployeesBelowAverageSalary
from (
select count(employee_id) TotalNumberOfEmployees,
avg(salary) AverageSalary
from employees
) preagg
left join employees e on e.salary < preagg.AverageSalary
group by TotalNumberOfEmployees,
AverageSalary
Note: I used a LEFT join so if you had 3 equal employees, it would show 0 instead of no results (nobody below below average).
It isn't clear which columns you want in your result set, which makes it difficult to answer your question. Making the question clear improves the quality of the answers.
You seem to want 3 facts:
Number of employees.
Average salary.
Number of employees earning less than the average salary.
And you show a query which does the job for the first two facts:
SELECT COUNT(*) AS NumberOfEmployees,
AVG(Salary) AS AverageSalary
FROM Employees
What's the difference between COUNT(*) and COUNT(Employee_ID)? The difference is that the latter only counts the rows where there is a non-NULL value in the Employee_ID column. A good optimizer will recognize that Employee_ID is a primary key and contains no NULL values, and the query will be the same. But COUNT(*) is more conventional and less reliant on the optimizer.
The other statistic can be generated as a simple value in the select-list via a sub-query:
SELECT COUNT(*) AS NumberOfEmployees,
AVG(Salary) AS AverageSalary,
(SELECT COUNT(*)
FROM Employees
WHERE Salary < (SELECT AVG(Salary) FROM Employees)
) AS NumberOfEmployeesPaidSubAverageWages
FROM Employees
Under many circumstances, it would not be appropriate to write the sub-query like that, but for the interpretation of the specified query, it is fine.
select * from <table name> where salary < (select avg(<salary column name) from <table name>);
Example:
select * from EMPLOYEE where sal < (select avg(emp_sal) from EMPLOYEE);
SELECT e.ename,e.deptno,e.sal,d.avg
FROM emp e,(SELECT deptno, avg(sal) avg
FROM emp
GROUP BY deptno) d
WHERE e.deptno=d.deptno
AND
e.sal < d.avg
To simplify, if I had a table called 'employee':
id INT NOT NULL PRIMARY KEY,
salary FLOAT,
department VARCHAR(255)
I want to perform and query where I retrieve the minimum salary in each department.
So my query is something like this:
SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
But regardless of which records are found. The ID values in the result set are renamed to 1,2,3.... up to however many records (departments) exist in the result set.
How can I maintain the actual ID's of the employees after performing the AGGREGATE function and GROUP BY?
You can't. Think about it, If a Department has 20 employees, and for that department, there are three employees that have the same minimum salary, which EmployeeId do you want the the query output to display? if it was guaranteed that there was only one employee in each dept with that lowest salary, then it can be done by selecting the specific employee records where the salary is the minimum value for each Department:
Select EmployeeID
From Employee e
Where Salary =
(Select Min(Salary) From EMployee
Where DepartmentId = e.DepartmentId)
but this will return multiple records per department when more than one employee has that min salary level.
I would guess you're using MySQL or SQLite, because your query is ambiguous and isn't allowed by standard SQL or most brands of RDBMS. MySQL and SQLite are more permissive, so it's your responsibility to resolve the ambiguity.
Here's my usual fix:
SELECT e1.ID, e1.salary, e1.department
FROM employee e1
LEFT OUTER JOIN employee e2 ON (e1.department = e2.department
AND e1.salary > e2.salary)
WHERE e2.department IS NULL;
Here's another solution that gives the same result:
SELECT e1.ID, e1.salary, e1.department
FROM employee e1
JOIN (SELECT e2.department, MIN(e2.salary) AS min_salary
FROM employee e2 GROUP BY e2.department) d
ON (e1.salary = d.min_salary);
Both of these give multiple rows per department if there are multiple employees in the department with identical minimal salaries. You need to decide how to resolve that case, because it's not clear from your problem description.
Your script is invalid:
SELECT employee.ID, MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
Instead, look at this:
SELECT MIN(employee.salary), employee.department
FROM employee
GROUP BY employee.department
If you need the employee id as well, then you need to use a subquery.
This will do the trick:
SELECT employee.department, MIN(employee.salary), employee.ID
FROM employee
GROUP BY 1
In modern SQL Server releases (and other reasonably powerful and modern SQL engines), SQL "Window functions" are probably the best alternatives (to be preferred over subqueries and self-joins) to do what you desire:
SELECT ID, salary, department
FROM employee
WHERE 1 = ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary ASC)
This works when, if multiple employees have the same (department-minimal) salary, you want just a "random-ish" one of them (you can add criteria to the ORDER BY if you want one picked by some specific criteria); look into RANK, instead of ROW_NUMBER, if you want all.