SQL QUERY ON EXISTS CLAUSE - mysql

1) Query:
SELECT INS_NAME
FROM INSTRUCTOR
WHERE EXISTS(SELECT DEPT_NAME
FROM DEPARTMENT
WHERE DEPT_ID = INSTRUCTOR.DEPT_ID AND DEPT_BUILDING = 'JOHNS');
2) Query:
SELECT INS_NAME
FROM INSTRUCTOR
WHERE EXISTS(SELECT DEPT_NAME
FROM DEPARTMENT
WHERE DEPT_BUILDING = 'JOHNS');
codes 1 and 2 produce different outputs please help me understand the reason.
(INSTRUCTOR TABLE)
ins_id ins_name dept_id ins_sal tax
27 DHIRAJ 4 200
28 RAHUL 4 500
34 HIO 4 100 2
90 SURYA 5 120 30
33 VINNY 6 100 11
(DEPARTMENT TABLE)
DEPT_BUILDING DEPT_NAME DEPT_ID
THOMAS BIO 4
JOHNS CHEM 5
JOHNS CSE 6

The second query returns all records from the instructor table because there are 2 records in the department table where DEPT_BUILDING='JOHNS'. Thus the exists() returns true for every record.
The first query returns only the last 2 records from the instructor table because the exists() also tests for a match in the department id and department no 4 does not have a building called johns.

Related

Query that provides the names of the recruiters that hire more than 3 employees, and the number of employees that were not hired by a recruiter

I'm a bit stuck on this question and was hoping for some help. Here's where I'm at currently.
I have this TEST table of Names. Each Person can either be a recruiter or an employee. The number in Recruited_by is associated with the person_id.
Person_id Name Recruited_by
1 Jean Grayson 1
2 Paul Smith 7
3 John Do Null
4 Alex Lee 7
5 Lisa Kim 7
6 Bob Thompson 3
7 Mike Keen Null
8 Raymond Red 3
9 Alisson Jones 1
10 Kate James 3
Here is the query I have so far which I'm trying to the names of the recruiters that hire more than 3 employees (which will return nothing in this case) and the number of employees that were NOT recruited by anyone (which would be the NULL names).
SELECT T.Name as Employees, COUNT(T1.Name) as Not_hired
FROM Test AS T
WHERE COUNT(T1.Name) IS NULL
LEFT OUTER JOIN Test AS T1
ON T.Recruited_by = T1.Person_id
GROUP BY T.Name
HAVING COUNT(T1.Name) > 3
However this query is returning nothing when I should expect it to return the number of employees who were not hired by a recruiter!
If you want in the results only 1 row with 2 columns then you can do a LEFT join of the table to a query that aggregates to get the ids of the persons that hired more than 3 persons and aggregate again to get the number of persons that were not recruited by anyone:
SELECT GROUP_CONCAT(CASE WHEN t2.Recruited_by IS NOT NULL THEN t1.Name END ORDER BY t1.Name) names,
SUM(t1.Recruited_by IS NULL) total_not_recruited
FROM Test t1
LEFT JOIN (
SELECT Recruited_by
FROM Test
GROUP BY Recruited_by
HAVING COUNT(*) > 3
) t2 ON t2.Recruited_by = t1.Person_id;
You will get the names of the persons that hired more than 3 persons (if they exist) as a comma separated list.
See the demo.

How to check if a non-string value exists in a record set generated from GROUP?

I have 3 tables,
-- table of selected_courses
student_id course_id
1 11
1 12
1 13
2 11
2 12
3 12
3 13
4 11
-- table of students
student_id name
1 Adam
2 Bill
3 Calvin
4 David
-- table of courses
course_id name
11 math
12 physics
13 chemistry
I would like to find those students who selected both physics(12) and chemistry(13), generally, in this case they should be Adam and Calvin.
Generally, I can get each student's course records by grouping
select * from selected_courses group by student_id;
then how can I find out if both 12 and 13 are in the student's group?
BTW, I am using mysql.
use aggregation
select student_id from
selected_courses a
where course_id in (12,13)
group by student_id
having count(distinct course_id)=2
Use correlated subquery
select student_id, course_id
from tablename a where exists
(select 1 from tablename b where a.student_id=b.student_id and course_id in (12,13) having count(distinct course_id)=2)

How to select rows with same values in one column but all must be different between each other in another column

Hello everyone i will try to be as specific and precise as possible.
I was looking around for answer to my problem and in mean time i made 2 tables
In first table i have names of Companies and their id-s.
In second table i have names of Employees,their id-s,the cities in which they live,and idK-s(its supposed to match id id-s from previous table) of Companies they work in.
I am supposed to select names of Companies that have at least four(3 or more) employees living in different cities compared to each other.
In order for things to be more clear i am going to give an example:
table1:
id name
1 Company1
2 Company2
3 Company3
4 Company4
5 Company5
6 Company6
table2:
id name city idK
1 EMP1 city1 1
2 EMP2 city2 1
3 EMP3 city3 1
4 EMP4 city4 1
5 EMP5 city1 2
6 EMP6 city2 2
7 EMP7 city3 2
8 EMP8 city1 3
9 EMP9 city2 3
10 EMP10 city3 3
11 EMP11 city1 4
12 EMP12 city2 4
13 EMP13 city3 4
14 EMP14 city4 4
15 EMP15 city5 4
16 EMP16 city1 5
17 EMP17 city2 5
18 EMP18 city1 5
19 EMP19 city3 5
20 EMP20 city3 5
21 EMP21 city2 5
22 EMP22 city1 6
23 EMP23 city8 6
24 EMP24 city1 6
25 EMP25 city15 6
I made spaces so it is easier to see.
So in idK=1 we have four employees and all are from different city compared to each other so Company1 should be in results.
idK=2 and idK=3 have under four employees in general so Company2 and Company3 are out.
idK=4 is good same reasons as idK=1 but idK=5 and idK=6 are out because while they have four or more employees they are not from different cities compared to each other.
I found similar problems as mine and some solutions but none were good enough for me or i just couldn't make them work so i would be very grateful if someone could explain to me what to do in this situation.
This will work here.
select t1.name from table2 t2
inner join table1 t1 on t2.idK = t1.id
group by t2.idk,t1.name
having count(distinct city) > 3
This is the data I used to test on db-fiddle.
CREATE TABLE table2 (id int, name varchar(100), city varchar(100), idK int);
INSERT INTO table2 (id,name,city,idK)
VALUES (1,'EMP1','city1',1),
(2,'EMP2','city2',1),
(3,'EMP3','city3',1),
(4,'EMP4','city4',1),
(5,'EMP5','city1',2),
(6,'EMP6','city2',2),
(7,'EMP7','city3',2),
(8,'EMP8','city1',3),
(9,'EMP9','city2',3),
(10,'EMP10','city3',3),
(11,'EMP11','city1',4),
(12,'EMP12','city2',4),
(13,'EMP13','city3',4),
(14,'EMP14','city4',4),
(15,'EMP15','city5',4),
(16,'EMP16','city1',5),
(17,'EMP17','city2',5),
(18,'EMP18','city1',5),
(19,'EMP19','city3',5),
(20,'EMP20','city3',5),
(21,'EMP21','city2',5),
(22,'EMP22','city1',6),
(23,'EMP23','city8',6),
(24,'EMP24','city1',6),
(25,'EMP25','city15',6);
Create TABLE table1 (id int,name varchar(100));
INSERT INTO table1 (id,name)
VALUES (1,'Company1'),
(2,'Company2'),
(3,'Company3'),
(4,'Company4'),
(5,'Company5'),
(6,'Company6');
You can use count(DISTINCT columnname) to get the number of unique values in a column.
SELECT
c.`name`,
COUNT(DISTINCT e.`city`) as `Num Cities`
FROM `companies` c
JOIN `employees` e
ON c.`id` = e.`idK`
WHERE COUNT(DISTINCT e.`city`) > 3
GROUP BY c.`name`
ORDER BY c.`name`
I expect this is what you are looking for
select idk
from table2
group by idk
having count(distinct city) > 3

Fetch rows which belonging to the parent category which has more than two rows

I have some combination of company and members
Member Table
id company_id companymember
1 1 john
2 1 Tam
3 2 haya
4 1 lee
5 3 kih
6 3 wild
7 3 cream
8 3 earth
What I want to pick up is
the 3 member names which belonging to the company which has more than two members
What I want is like this
company_id 2 has only 1 member, 3rd row is not selected
company_id 3 has 4 members, so 8th row is not selected
My Goal
1 1 john
2 1 Tam
4 1 lee
5 3 kih
6 3 wild
7 3 cream
I could make it , pick up company_ids first and
loop each id by script and fetch.
However in this way, it exec sql many times.
Is there any good way to do this on MySql by one sentence SQL??
Try this
select id,company_id,companyMember
from (Select id
,company_id
,companyMember
,Row_Number() OVER(PARTITION BY company_id ORDER By company_id) AS TotalCount
from MemberTable
) as Table1
where TotalCount <=3 and Company_id in(
Select Company_id
from MemberTable
group by Company_id
having COUNT(Company_id) >=3
)
order by id

SELECT sql with four different tables with primary key and foreign key

For my database, having these four table
First one, DEPARTMENT
//DEPARTMENT
D# DNAME
------------------
1 RESEARCH
2 IT
3 SCIENCE
Second one, EMPLOYEE
//Employee
E# ENAME D#
-----------------------
1 ALI 1
2 SITI 2
3 JOHN 2
4 MARY 3
5 CHIRS 3
Third, PROJECT
//PROJECT
P# PNAME D#
-----------------------
1 Computing 1
2 Coding 3
3 Researching 3
Fourth, WORKSON
//WORKSON
E# P# Hours
--------------------
1 1 3
1 2 5
4 3 6
So my output should be something like
E# ENAME D# TOTAL HOURS/W
--------------------------------------------
1 ALI 1 8
2 SITI 2 0
3 JOHN 2 0
4 MAY 3 6
5 CHIRS 3 0
Display 0 because the employee has no project to works on.
my currently statement using
SELECT E#,ENAME,D# and sum(Hours) as TOTAL HOURS/W
FROM EMPLOYEE,PROJECT,WORKSON
WHERE EMPLOYEE.P#
no idea how should it select
You should use an left join like this. You only need 2 tables employee and workson.
Try this query:
SELECT e_tbl.E#, e_tbl.ENAME, e_tbl.D#,
coalesce(SUM(w_tbl.Hours), 0) as "Total Hours/W"
FROM
EMPLOYEE e_tbl LEFT JOIN WORKSON w_tbl
ON e_tbl.E# = w_tbl.E#
GROUP BY e_tbl.E#
You need to use GROUP BY and JOINS , in order to achieve your output
SELECT E.E#,
E.ENAME,
E.D#,
sum(Hours) AS TOTAL HOURS/W
FROM Employee AS E
JOIN WORKSON AS W ON E.E# = W.E#
GROUP BY E.E#,
E.ENAME,E.D#
Use this :)
With the given output you do not need to join all the tables, and this could be done by joining employee and works on as
select
e.`E#`,
e.ENAME,
e.`D#`,
coalesce(tot,0) as `TOTAL HOURS/W`
from Employee e
left join
(
select `E#`,
sum(Hours) as tot
from WORKSON
group by `E#`
)w
on w.`E#` = e.`E#`
group by e.`E#`
DEMO