Finding teacher that only taught one class - mysql

I want to ask what would I add to my query to select the ones that only taught one class. My table is:
Teacher Course
ID Name Course_ID Teacher_ID
1 George 1 1
2 Sam 2 2
3 Julie 3 1
I want to get the teacher ID who only taught one class. I have:
select teacher.id
from teacher, course
where teacher.id = course.teacher_id;
I was thinking of adding
having (count(course.teacher_id)) = 1
or
where count(t) = (select count(*) from course) and t = 0
but I get an "invalid use of group error". How do I change it to fix my query?

What you have tried is almost there, just add group by, and use join not , to combine tables:
select teacher.id
from teacher
join course
on teacher.id = course.teacher_id
group by teacher.id
having (count(course.Course_ID)) = 1 -- note count(Course_ID), not count(teacher_id)

Please try below code.Hope this will helps.
select teacher.id
from teacher, course
where teacher.id = course.teacher_id
GROUP BY course.teacher_id
HAVING COUNT(course. Course_ID) =1

Join with a group by and having:
select *
from teacher
where id in (
select teacher_id
from course
group by teacher_id
having count(*) = 1)

Related

SQL -- Finding students taking 2 or more classes

I had this question in an interview, and I couldn't quite figure it out. I have three tables: a student table, a classes table and a table linking the other two. Here is a basic schema for them.
STUDENT
student_id | student_name
-----------+-------------
int | varchar(30)
CLASS
class_id | class_name
---------+-----------
int | varchar(30)
ROSTERS
student_id | class_id
-----------+---------
int | int
The rosters table shows which students are taking which classes. How do I write a query showing which students are taking 2 or more classes?
This query will do what you want:
SELECT s.student_name, COUNT(DISTINCT r.class_id) AS num_classes
FROM student s
LEFT JOIN rosters r ON r.student_id = s.student_id
GROUP BY s.student_id
HAVING num_classes >= 2
It counts all the distinct class_id values in roster for each student (num_classes) and returns only students with 2 or more (HAVING num_classes >= 2).
Note I've used a LEFT JOIN to catch all students, however since you want only those with more than 1 class this is not necessary and you could use a straight JOIN.
Also note that it's not necessary to JOIN the class table for this question, however if you wanted the names of the classes the student was taking you would need to.
You can use join, count, having and group by to get the required output:
select r.student_id,s.student_name,count(*)
from STUDENT s inner join ROSTERS r
on s.student_id = r.student_id
group by r.student_id,s.student_name
having count(*)>=2;
You need to join the two tables, STUDENT and ROSTERS (I have used inner join, if required, this can be changed as per requirements), counting the number of classes each student is taking.
SELECT s.student_name,
COUNT(r.class_id) AS count
FROM
STUDENT s
INNER JOIN
ROSTERS r
ON
r.student_id = s.student_id
GROUP BY
s.student_id
HAVING
count >= 2
this will work:
select s.*,r.*,c.*,count(*)
from
student s,
class c,
rosters r where
s.student_id=r.student_id and
c.class_id=r.class_id
group by s.student_id
having count(*)>=2
SELECT COUNT(class_id), student_id
FROM Rosters
GROUP BY student_id
HAVING COUNT(class_id) >=2
This is the simplest way to do it IMO.

SQL inner join wrong output from two tables

Students Table:
ID | Family_ID | Student_name | F_name
Families Table:
ID | F_name | Contact_No
i want to get all records from students where family_id is repeating.(basically i want to know students Brothers/Sisters records if there is any in student table.
i tried it this way but got wrong output;
SELECT students.*
FROM students
INNER JOIN families
ON families.id = students.family_id
ORDER BY families.id ASC
my query result in image: as you can see some ids are showing once others are more then once, but i think all should appear more then once.
If you want to see only relevant people you don't need to link it to the families table. You can group the student with family_id. Here is your query :
SELECT *
FROM Student
WHERE family_id IN (SELECT family_id
FROM students
GROUP BY family_id
HAVING COUNT(1)>1)
ORDER BY family_id
You could try using a join on subquery for the family_id that have more that one rows in students
SELECT students.*
FROM students
inner join (
select students.family_id
FROM students
group by students.family_id
having count(*)>1
) t on t. family_id = students.family_id

how to get Intersection of two query in mysql

I have a table that has two column with two foreign key from two different table.
this is my relation table:
I want to select those student who can speak both language with id 3 and 4.
How can i wrote a query to give me for e.x 12 , 14
You can give it a try:
SELECT
student_id,
COUNT(*) total
FROM your_table
WHERE language_id IN (3,4)
GROUP BY student_id
HAVING COUNT(*) = 2;
Only IN doesn't ensure that a student is involved both in language id 3 & 4.
You need to use GROUP BY student_id HAVING COUNT(*) = 2 in order to ensure those student_ids to be in the result who were involved both in language id 3 & 4
Another solution would be using INNER JOIN. But it doesn't scale.
SELECT
A.student_id
FROM your_table A
INNER JOIN your_table B ON A.student_id = B.student_id
AND A.language_id = 3 AND B.language_id = 4
Assume your relation is named "my-relation":
SELECT R1.student_Id FROM my-Relation R1 join my-Relation R2 on R1.student_id = R2.student_id where R1.language_Id = '3' and R2.language_id = '4'

How do I delete duplicate values with group by

Example database :
ID StudentName StudentClass
1 John A
2 John B
3 Peter A
4 John A
5 John B
I want the result should be
ID StudentName StudentClass
1 John A
2 John B
3 Peter A
Statment
DELETE FROM Student
WHERE ID NOT IN (SELECT *
FROM (SELECT MIN(n.ID)
FROM Student n
GROUP BY n.StudentName) x)
How do I keep John name on class A & B?
DELETE a FROM Student a
LEFT JOIN
(
SELECT MIN(ID) AS minid
FROM Student
GROUP BY StudentName, StudentClass
) b ON a.id = b.minid
WHERE
b.minid IS NULL
A better method to disallow even insertion of such duplicates would be multi-column unique index(it will optimize your searches too). Here is how:
ALTER TABLE `Student`
ADD UNIQUE INDEX `idx` (`StudentName`, `StudentClass`)
You should be able to join Students against itself, with a JOIN predicate that ensures the JOIN matches duplicate students, and delete the join'd row:
DELETE
duplicate_students.*
FROM Students JOIN Students as duplicate_students
ON Students.StudentName = duplicate_students.StudentName
AND Students.StudentClass = duplicate_students.StudentClass
AND duplicate_students.ID > Students.ID
NOTE: Please back up your data first; I take no responsibility for lost data :-) This is a conceptual idea and has not been tested.
This should work:
DELETE S FROM Student S
INNER JOIN(
SELECT MIN(ID) AS ID,StudentName,StudentClass FROM Student
GROUP BY StudentName,StudentClass
) S2 ON S.ID != S2.ID AND S.StudentName = S2.StudentName AND S.StudentClass = S2.StudentClass
Its basically selecting the minimum ID out of all the duplicate records in sub query. Then we simply delete everything that matches that Class and Name, But we don't match the Minimum Id, so at end of day, we are keeping (presumably) 1st record out of duplicates and eradicating rest.

MySQL query the largest amount present in a collection

I have a table Teacher that contains a TeacherPIN as well as a table Student that contains a TeacherPIN referencing a Teacher. The idea is that a Teacher contains a certain amount of Students.
I am tasked with finding the teacher with the most students. I am currently using the query:
select t.TeacherPIN, count(s.TeacherPIN)
from Teacher t, Student s
where t.TeacherPIN = s.TeacherPIN
and ((select count(s1.TeacherPIN) from Student s1 where s1.TeacherPIN = t.TeacherPIN) >=
(select count(s2.TeacherPIN) from Student s2 where s2.TeacherPIN = (select t1.TeacherPIN from Teacher t1)));
I'm sure I'm making this way more complicated than I should be, but I've been at it for a while now and am hoping someone could push me in the right direction.
Thanks!
To find just one teacher (of possibly many) with maximum number of students:
SELECT TeacherPIN
, COUNT(*) AS NumberOfStudents
FROM Student
GROUP BY TeacherPIN
ORDER BY NumberOfStudents DESC
LIMIT 1
To find all of them:
SELECT TeacherPIN
, COUNT(*) AS NumberOfStudents
FROM Student
GROUP BY TeacherPIN
HAVING COUNT(*) =
( SELECT COUNT(*) AS NumberOfStudents
FROM Student
GROUP BY TeacherPIN
ORDER BY NumberOfStudents DESC
LIMIT 1
)