MySQL SELECT join 3 tables with conditions for all rows - mysql

I need some help to create my select correctly...
Here is my tables :
**teacher** :
id
name
**classroom** :
id
teacher_id
**students** :
id
name
classroom_id
status
I am trying to select all the teachers that have a classroom.
Classroom may be selected only if ALL students have a status > 10...
If a student has a status 5 for example the classroom may NOT be selected and therefore the teacher may NOT be selected (besides he has a another OK classroom)

try this :
select * from teacher t
inner join classroom c on t.id=c.teacher_id
inner join
(select * from students
group by classroom_id having classroom_id not in
(select distinct classroom_id from students where status<=10)) s
on s.classroom_id=c.id
updated :
from your comment i think query above should work but you can test this query :
select * from teacher t where id in
(select distinct teacher_id from classroom where id in
(select distinct classroom_id from students
group by classroom_id having classroom_id not in
(select distinct classroom_id from students where status<=10)
)
)

Related

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

MySQL get count from two related tables

I am using MySQL and database server and I have two tables one is for customer and another for customer_contacts.
Here are the table structures:
customer(
id(pk, ai)
name
email
)
and
customer_contacts(
id(ai)
customer_id
first_name
last_name
)
Now my question is:
lets say I have one customer has many customer_contacts like this
customer
id name email
1 john john#example.com
and customer_contacts is like this (first row)
id customer_id first_name last_name
1 1 john doe
2 1 johnp pual
like this
So here I want to get all the contact details count for the id john. So can some one tell me how to get that?
Any help and suggestions will be really appreciable. Thanks
If the id is already known (as suggested by the question, it would be a plain
SELECT COUNT(*) from customer_contacts
WHERE customer_contacts.id = 1;
You just need to know the number of contactacs for the customer John, right?
SELECT COUNT(*)
FROM customer cus INNER JOIN customer_contacts con ON cus.id = con.customer_id
WHERE cus.name = 'john'
Nevertheless, It would be better if you know the id of John. Your query would be this:
SELECT COUNT(*)
FROM customer_contacts
WHERE customer_id = 1
Simply join both tables and use count() with group by c.id use where to filter records
select c.*,
count(*) total_contacts
from customer c
left join customer_contacts cc on(c.id = cc.customer_id)
group by c.id
Fiddle Demo

MySQL: Selecting records that attended two different courses out of 3

I have two tables, a course and an attendance table.
Course table keeps records of offered courses
Attendance table keeps records of students names and emails who attended courses offered and the date they attended.
I need to select all attendance records in which student has attended exactly 2 out of 3 courses offered and output the 3rd unattended course needed to complete the 3 courses.
Course table structure:
id : int
course_title : varchar
course_level : int
Attendance table structure:
id : int
course_id : int
student_name : varchar
student_email : varchar
attended_date : date
Try this solution (as found here)
SELECT t1.email, course.course_title
FROM (SELECT email
FROM attendance
JOIN course
ON attendance.course_id = course.id
AND course.course_level = 1
GROUP BY email
HAVING COUNT(DISTINCT attendance.course_id) = 2) AS t1
CROSS JOIN course
LEFT JOIN attendance
ON attendance.course_id = course.id
AND attendance.email = t1.email
WHERE course.course_level =1
AND attendance.id IS NULL;

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.

Creating a view to get name of student who obtained maximum mark in every course

Course table : courseId,courseName,tutor
Student table: studentId,studentName
Marks table: marksId,studentId,courseId,marks
If more info is needed plz comment
<\br>
CREATE VIEW maxmarks
AS
SELECT b.studentName,courseId from [dbo].[zz_16_Marks_tbl] a,[dbo].[zz_16_Student_tbl] b
WHERE a.studentId=b.studentId AND marks in(
SELECT MAX(marks),courseId FROM [dbo].[zz_16_Marks_tbl] GROUP BY courseId)
CREATE VIEW maxmarks
AS
WITH CTE AS (SELECT MAX(marks),courseId FROM [dbo].[zz_16_Marks_tbl] GROUP BY courseId )
SELECT b.studentName,a.courseId
from [dbo].[zz_16_Marks_tbl] a
INNER JOIN [dbo].[zz_16_Student_tbl] b ON a.studentId=b.studentId
INNER JOIN CTE c ON a.courseId =c.courseId and a.marks=b.marks