I have an employee table with duplicate instances of employees. For instance the last name Baba may show up 2 times with the same employee ID. I have to count last names from the table, but do not want to count the same one twice.
I am writing SQL in Postgres. Here is the table from which I draw my query:
CREATE TABLE Employee (
emp_no int NOT NULL,
birth_date date NOT NULL,
first_name varchar(100) NOT NULL,
last_name varchar(100) NOT NULL,
gender varchar(100) NOT NULL,
hire_date date NOT NULL,
CONSTRAINT pk_Salaries PRIMARY KEY (
emp_no
)
);
The data was given and contained duplicates. I cannot remove the duplicates but do not want to count them. Here is my query statement:
SELECT Employee.last_name, COUNT(Employee.last_name) AS "Last Name Count"
FROM Employee
GROUP BY Employee.last_name
ORDER BY "Last Name Count" DESC;
The output works well but I am sure it is counting some last names more than once.
I have tried adding a WHERE cause to get a count of last names where the emp_no is distinct but it does not work.
You want to count last names from the table, but do not count the same one twice.
So try this :
"SELECT Employee.last_name, COUNT(DISTINCT Employee.last_name) AS "Last Name Count" FROM Employee GROUP BY Employee.last_name"
The emp_no is a primary key, so it has to be unique and a where clause with distinct would have no impact. The query seems to be accurate, I'd be surprised if it's counting last names more than once.
Just use distinct keyword during applying the COUNT() aggregation :
SELECT e.last_name, COUNT(distinct e.last_name) AS "Last Name Count"
FROM Employee e
GROUP BY e.last_name
ORDER BY "Last Name Count" DESC;
You should try validating if the first name is counted uniquely by each last name
something like this
SELECT Employee.last_name, COUNT(distinct Employee.first_name) AS "Last Name Count"
FROM Employee
GROUP BY Employee.last_name
ORDER BY "Last Name Count" DESC;
see fiddle
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=f0a9568e6cb5fb5e0247d2f2c5e95114
or if necessary check if more data is repeating in both lines, doing something like
select distinct * from (
SELECT Employee.last_name,
COUNT(*) over (partition by first_name, birth_date, last_name, gender) AS n
FROM Employee
) V
where n > 1
see the fiddle
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=223143f0d603abf30d99ad87fa07781e
Thank you all for your quick responses. They were all very good and helpful!
I ran the following code to find that I was wrong and each individual had only one instance in the table and had only one unique employee ID (emp_no).
SELECT Employee.emp_no, COUNT(Employee.emp_no) AS "Employee ID Count"
FROM Employee
GROUP BY Employee.emp_no
ORDER BY "Employee ID Count" ASC;
Again, thank you all very much!
Related
I have a table:
TABLE employee (
ID bigint,
name varchar,
department bigint
);
I would like to find a department that has minimal employees. (Count of rows in this table)
I believe this would require a HAVING statement with a nested sub-query, any help would be much appreciated.
I am using H2 database.
You could group by department and get the count of users in each department, order by the count and select top 1?
SELECT TOP 1
[department],
COUNT(*) AS [NoOfEmployees]
FROM [employee]
GROUP BY [department]
ORDER BY COUNT(*) ASC
I have employee table with emp id (emp_id) and department (dep_id) fields. An employee could be working in more than one Department. I want to write a sql query to display unique emp_ids who work in more than one department.
Pl help me to write sql query.
Thx
Answered here: SQL query for finding records where count > 1
You need to use count, group by and having like this.
select emp_id, count(dep_id)
from employee_department
group by emp_id
having count(dep_id)>1
Query
SELECT COUNT(*)
FROM
(
SELECT id_employee, COUNT(*) AS CNT
FROM Department_Employee
GROUP BY id_employee
) AS T
WHERE CNT > 1
I have a table Employees, which has Fields as below:
Employee_name,Employee_id,Employee_status,Employee_loc,last_update_time.
This table does not have any constraint.
I have tried the below query.
select Employee_name, count(1)
from Employees
where Employee_status = 'ACTIVE'
Group by Employee_name,Employee_loc
having count(Employee_name) > 1
order by count(Employee_name) desc
In the select, I need to get Employee_id too.. Can any one help on how to get that?
You can just add Employee_id to the query, and also add it to the group by clause. (Adding it to the grouping won't make any difference in the query results, assuming each employee name each employee id is unique).
If the grouping does make a difference, that implies that some combinations of employee name and location have more than one ID associated with them. Your query would therefore need to decide which ID to return, possibly by using an aggregate function.
SELECT EMPLOYEE_NAME, EMPLOYEE_ID, COUNT(1)
FROM
EMPLOYEES
WHERE
EMPLOYEE_NAME IN
(
SELECT EMPLOYEE_NAME
FROM EMPLOYEES
WHERE Employee_status = 'ACTIVE'
GROUP BY Employee_name,Employee_loc
HAVING COUNT(*) > 1
)
GROUP BY EMPLOYEE_NAME, EMPLOYEE_ID
You can also use partition by clause and select whichever columns you want to see irrespective of the columns you are using for aggregation.
A very short and simple explanation here - Oracle "Partition By" Keyword
I have an 'employee' table with
create table employee
(
e_number int,
e_name varchar(20),
salary money,
hire_date date
)
Now I want to display only the name of the employees who have the same name but different salary.
I tried select e_name,count(*) from employee group by e_name having count(*)>1;
but cannot combine it with "the same salary" section. Any help?
This assumes that you want the names of both of the people listed:
SELECT e1.e_name
FROM employee e1, employee e2
WHERE e1.e_name = e2.e_name
AND e1.salary <> e2.salary;
If you only want each name listed once, you would use a SELECT DISTINCT instead of the SELECT.
If your goal is to express this in the having clause:
Select name
from employee
group by name
having
count(*) > 1
and min(salary) != max(salary)
order by name
SELECT employee1.e_name, employee1.Salary, Employee2.Salary
FROM Employee employee1
JOIN Employee employee2
on employee1.name = employee2.name
AND Employee1.Salary <> Employee2.Salary
AND Employee1.E_Number <> employee2.E_Number
Basically get every employee, join it to every other employee via name, where the employee number is different (so don't join to yourself) and salary is different.
You probably don't need to check that employee number is different because 1 employee can only have 1 salary in your table design
Use a join, but importantly use a greater-than comparison, rather than a not-equals, to avoid duplicates:
SELECT e1.e_name as name1, e2.e_name as name2
FROM employee e1
JOIN employee e2 ON e1.e_name = e2.e_name
AND e1.salary > e2.salary;
Note also that the ON condition contains the salary comparison. It is a common misconception that the join on condition may only contain key-related comparisons. Doing this can have significant performance benefits, especially when further joins are made, because the ON condition is executed as the rows are joined - which discards non-matches immediately, whereas WHERE conditions are executed as a filter on the entire result set of the joins.
You just want the count of distinct salaries, not the count of all records.
select e_name,count(distinct salary)
from employee
group by e_name
having count(distinct salary)>1
(Drop the count in the select if unneeded - included since it was in your example)
First filter salary not double (not in), then grouping by e_name having count > 1
SELECT A.e_name
FROM employee A
WHERE A.salary NOT IN (SELECT salary FROM employee WHERE id != A.id)
GROUP BY A.e_name
HAVING COUNT(A.e_name) > 1
I have tables which looks like below.
Employee table
Date Employee ID Employer ID Salary
2/3/2011 10 20 45666
3/12/2009 43 53 2356
Employer Table
Employer ID State
53 OH
42 MI
Trying to get the total salary by month and by state using group by clause. But not getting the results. what am i doing wrong?? any help appreciated
select date, sum(salary) from employee
group by to_char(date,'MON')
select sum(salary) from employee A, Employer B
where A.employer id=B.employer id
group by B.state
Also i need to get the top 10 distinct employee ids based on their salary
select DISTINCT employee id from employee
where rownum<=10
order by salary desc
You have to group by the exact expression in your select list, e.g.,
select to_char(date,'MON'), sum(salary)
from employee
group by to_char(date,'MON');
You probably want to include the state in your second query:
select b.state, sum(salary)
from employee A, Employer B
where A.employer_id=B.employer_id
group by B.state;
Generally speaking, stating in your question that you're "not getting the results" is not very helpful to the folks you're asking help of. Please provide any error messages or output that describes what "not getting the results" means.