How can i used subsery to update column - mysql

I have an EMPLOYEE table below:
EMP_ID DEPT_ID
101 1
102 2
103 3
104 1
And a DEPARTMENT table as:
DEPT_ID COUNTS
1
2
3
I want to write a query which would count the number of Employee that belong to a department and store it into Department column table so the Department table will look like:
DEPT_ID COUNTS
1 2
2 1
3 1
I tried:
update department p
set p.counts = (select count(*) from EMPLOYEE e where p.dept_id = e.dept_id
group by e.dept_id)
but it doesn't work.

Remove the group by and the first alias:
update department p
set counts = (select count(*) from EMPLOYEE e where p.dept_id = e.dept_id);

Related

Find common employees between departments

I'm using MySQL. I have a table called works(EID,DID,PCT_TIME) and PCT_TIME is not used here.
The question I have is: Find the two departments ( represented by DID) who have the highest number of employees ( he's represented by EID) in common.
I've tried that:
select count(*) as max_NBR_COMMUN from (select EID from WORKS group by EID having count(EID) >= 2) as temp
to get the number of employees common to two departments but it doesn't work.
EDIT: I've seen your answer and I thank you all, I'm a business student so not familiar with computer science and therefore sql.
So my final request is
select count(distinct wa.eid) as num_eids_in_common, wa.did, wb.did
from works wa
join works wb on wa.eid = wb.eid and wa.did < wb.did
group by wa.did, wb.did
order by num_eids_in_common desc
limit 1
Let's start with this.
create table works ( eid int not null, did int not null );
insert into works values (1,1), (1,1), (1,2), (1,3), (2,1), (2,2), (3,1), (4,4);
select * from works order by eid;
eid did
---------- ----------
1 1
1 1
1 2
1 3
2 1
2 2
3 1
4 4
Note that employee 1 has multiple entries in department 1, a curve ball.
To find out which employees are in more than one department we need to join works with itself, a self-join. This is like any other join, but table aliases are mandatory.
select wa.eid, wa.did, wb.did
from works wa
join works wb on wa.eid = wb.eid
and wa.did != wb.did;
This joins with any row that has the same employee ID but different department ID, because we don't want to see employees in our own departments.
eid did did
---------- ---------- ----------
1 1 2
1 1 3
1 1 2
1 1 3
1 2 1
1 2 1
1 2 3
1 3 1
1 3 1
1 3 2
2 1 2
2 2 1
Employee 1 shows up multiples times because it has multiple entries in works, remember the curve ball? We can remove these duplicates by selecting only the distinct rows.
select distinct wa.eid, wa.did, wb.did
from works wa
join works wb on wa.eid = wb.eid
and wa.did != wb.did;
eid did did
---------- ---------- ----------
1 1 2
1 1 3
1 2 1
1 2 3
1 3 1
1 3 2
2 1 2
2 2 1
We can also avoid counting each department pair twice by joining with wa.did < wb.did instead of wa.did != wb.did.
select distinct wa.eid, wa.did, wb.did
from works wa
join works wb on wa.eid = wb.eid
and wa.did < wb.did;
eid did did
---------- ---------- ----------
1 1 2
1 1 3
1 2 3
2 1 2
Now we have a list of all the employees who are in more than one department, and their departments.
We get the number of employees in common by grouping by both department IDs and counting the employees.
select count(distinct wa.eid) as num_eids_in_common,
wa.did, wb.did
from works wa
join works wb on wa.eid = wb.eid
and wa.did < wb.did
group by wa.did, wb.did;
num_eids_in_common did did
------------------ ---------- ----------
1 1 3
1 2 3
2 1 2
Finally we get the one with the most in common by sorting num_eids_in_common in descending order and limiting it to 1 row.
select count(distinct wa.eid) as num_eids_in_common,
wa.did, wb.did
from works wa
join works wb on wa.eid = wb.eid
and wa.did < wb.did
group by wa.did, wb.did
order by num_eids_in_common desc
limit 1;
num_eids_in_common did did
------------------ ---------- ----------
2 1 2

SQL to check if the value is not present in table

I am working on following SQL:
select *
from `STUDENTLOC` l,
STUDENT s,
ATTENDANCE a
where l.STUDENTID = s.ID
and l.LOCID = 3
Now I need to make sure that the values are not already present in ATTENDANCE table. It has following structure:
ID StudentID ScheduleID
1 6 6
2 3 3
It is a simple list where I need to display list of students whose record have not been added in ATTENDANCE table.
You can use not exists:
select *
from `STUDENTLOC` l
join STUDENT s on l.STUDENTID = s.ID
where not exists (
select 1
from ATTENDANCE a
where a.STUDENTID = l.STUDENTID
)
and l.LOCID = 3
Also, always use modern explicit join syntax instead of comma based join syntax.
Example table student and table payments:
id_student name id id_student datepayment
1 Lisa 1 1 2017-01-01
2 2 1 2017-02-03
3 Asher 3 2 2017-03-05
4 Lee 4 1 2017-03-03
SELECT a.name, a.datepayment
FROM
(SELECT s.name, p.datepayment
FROM
students s
LEFT OUTER JOIN payment p ON s.id_student = p.id_student) AS a
WHERE datepayment IS NULL;
Result:
name datepayment
Asher NULL
Lee NULL

SELECT using GROUP BY and display the total with two tables

Having two tables
Department table
//Department
D# DNAME
-------------------
1 SALES
2 ACCOUNTING
3 GAMES
5 SPORTS
Project table
//Project
P# D#
-----------
1001 1
1002 3
1003 5
1004 5
When output display it should be something like:
Department Total Project
---------------------------
1 1
2 0
3 1
5 2
Currently my statement
SELECT D# FROM DEPARTMENT
WHERE (SELECT COUNT(*) FROM PROJECT WHERE DEPARTMENT.D# = PROJECT.D#);
but what should i display 0 if no any project in that D# ?
SELECT D.D#,
COUNT(p.P#)
FROM Department d
LEFT JOIN Project p
ON Project.D#=Department.D
GROUP BY d.D#;
Try This:
SELECT D# , CASE WHEN A.COUNT > 0 THEN D# ELSE 0 END AS TOTAL_PROJECT
FROM DEPARTMENT JOIN (SELECT D# , COUNT(*) FROM PROJECT GROUP BY PROJECT.D#) A ON
DEPARTMENT.D# = A.D#;
A simple left join with group by could achieve such requirement.
SELECT
DEPARTMENT.D#,
COUNT(PROJECT.P#) AS TotalProject
FROM DEPARTMENT
LEFT JOIN PROJECT ON DEPARTMENT.D# = PROJECT.D#
GROUP BY DEPARTMENT.D#
Check below query:
SELECT
D# as 'Dept_ID',count(P#) as 'Count'
from
department d
left join project p
on d.D#=p.D#
group by d.D#;

Update Duplicate column values based on Count in MySQl

I Have a Table like this
Employeeid Name CompanyID
1 Achal 1
2 Anil 1
3 Anil 1
4 Sachi 2
5 Anil 2
6 Sachi 1
7 Sachi 2
I want to update the names of the employee if multiple employees are there in a same company
My resultant table should be like this
Employeeid Name CompanyID
1 Achal 1
2 Anil(1) 1
3 Anil(2) 1
4 Sachi(1) 2
5 Anil 2
6 Sachi 1
7 Sachi(2) 2
My query is something like this
Update tblemplayee emp
join
(
select sname,count(*)
from tblemployee
group by sname,companyid
) innertable
on innertable.employeeid=emp.employeeid
set sname = concat(sname,'(', ,')') .
How can i change my query to get the result.
If you need to execute your query only once, you could use this query:
UPDATE
employees INNER JOIN (
SELECT e1.Employeeid, COUNT(e2.Employeeid) n
FROM
employees e1 INNER JOIN employees e2
ON e1.Name=e2.Name
AND e1.CompanyID=e2.CompanyID
AND e1.Employeeid>=e2.Employeeid
INNER JOIN (SELECT Name, CompanyID
FROM employees
GROUP BY Name, CompanyID
HAVING COUNT(*)>1) dup
ON e1.Name=dup.Name AND e1.CompanyID=dup.CompanyID
GROUP BY
e1.Employeeid, e1.Name) counts
ON employees.Employeeid = counts.Employeeid
SET
Name = CONCAT(Name, '(', counts.n, ')');
Please see fiddle here.

How to get records which does not have entry in 2nd table

for ex
department
id departmentname
1 x
2 y
3 z
employee
fkdepartmentid empname
1 john
1 sam
2 ram
3 hari
Here one empname can belong to any number of departments.
My requirement is get all the departments from department table where empname!=john (with a join).
I tried with the following query:
SELECT d.id FROM department d
INNER JOIN employee e ON d.id=e.fkdepartmentid
WHERE((e.empname<>'1')OR d.id IN (SELECT DISTINCT fkdepartmentid FROM employee WHERE fkdepartmentid NOT IN (SELECT DISTINCT fkdepartmentid FROM employee WHERE empname=sam)) ) GROUP BY d.id
However, the query is slow and failing in some scenarios.
the results should be 2 and 3. How can I achieve those results?
Here you go
SELECT * FROM department WHERE id IN( SELECT fkdepartmentid FROM employee WHERE empname !='john' GROUP BY fkdepartmentid )
If understand correctly you want to exclude department 1 because Jhon is an employer of that department. If it so you need to reverse the conditions.
Try
SELECT *
FROM department
WHERE id NOT IN
(
SELECT fkdepartmentid
FROM employee
WHERE empname = 'john'
GROUP BY fkdepartmentid
)
Output:
| ID | DEPARTMENTNAME |
-----------------------
| 2 | y |
| 3 | z |
Here is SQLFiddle demo
here is one which does not use nested queries:
SELECT t1.*
FROM department AS t1
LEFT JOIN employee AS t2
ON t2.deptid = t1.id AND t2.name IN ('john', 'rari')
WHERE t2.name IS NULL;
this lists all departments which does not have any employee with the name in list.