Properly using Not In clause - php

Here, the scenario is:
I have 4 tables
Course
Student
Department
EnrollCourse
While a student going to enroll a course a list of courses should be in dropdown from courses table. But course_id which are already in enroll_courses table shouldn't load in that courses dropdown. Because a student can't register single course 2 times. Here I'm using not in operation which will retrieve list of course_id which are not in enroll_courses table.
But I'm getting following error for the query:
You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near 'enroll_courses.course_id LIMIT 0, 25' at line 6
Here is query:
SELECT students.name, students.email,departments.name as d_name,
courses.name as c_name
FROM students JOIN departments on students.department_id=departments.id
JOIN courses on departments.id = courses.department_id
LEFT JOIN enroll_courses on enroll_courses.course_id=courses.id
WHERE courses.id NOT IN (enroll_courses.course_id) AND students.id=8
Anyone who can help me to find the solution?

Try like this,
SELECT students.name ,
students.email ,
departments.name AS d_name ,
courses.name AS c_name
FROM students
JOIN departments ON students.department_id = departments.id
JOIN courses ON departments.id = courses.department_id
JOIN enroll_courses ON enroll_courses.course_id = courses.id
WHERE students.id = 8
AND courses.id NOT IN ( enroll_courses.course_id );

There are several ways to get the desired result, this is close to your original query:
SELECT students.name ,
students.email ,
departments.name AS d_name ,
courses.name AS c_name
FROM students
JOIN departments
ON students.department_id = departments.id
JOIN courses
ON departments.id = courses.department_id
WHERE students.id = 8
-- up to here it's all possible courses
-- now remove already enrolled courses
AND courses.id NOT IN
(
SELECT course_id
FROM enroll_courses
WHERE student_id = 8
)
Or a Correlated version:
AND courses.id NOT IN
(
SELECT course_id
FROM enroll_courses
WHERE student_id = students.student_id
)
Or NOT EXISTS:
AND NOT EXISTS
(
SELECT *
FROM enroll_courses
WHERE student_id = students.student_id
AND course_id = courses.course_id
)

Related

Return one row for a table Left join with another table has multirow with same ID

customers table:
notes table:
MY SQL query didn't work
SELECT * FROM customers LEFT JOIN notes ON customers.customer_id = notes.customer_id GROUP BY notes.customer_id
I want to return one row for customer_id 277 :
Mr,Kevin, New notes, Service, 2017-06-17 12:37:28
New note 2, Lead, 2017-06-17 15:04:42
customers table left join with multi tables
You could use a group_concat on formatted result for notes
select a.customer_id, a.ttle, a.first_name, group_concat(t.note_row)
from customer
inner join (
select customer_id, concat(note, ' ', note_type, ' ', note_date_added ) as note_row
from notes
) t on t.customer_id = a.customer_id
group by a.customer_id, a.ttle, a.first_name

Multiple select queries with multiple where statements

I currently have this query:
SELECT s.firstName, s.lastName, sum(correct) AS score
FROM student s
JOIN test t ON s.id = t.studentid
WHERE t.testType = 1 GROUP BY lastName, firstName
But I also want it to show
WHERE t.testType = 2
and testType 3 and 4 also.
I want to have it all in the same row. Is this possible?
You could use the in style to select from a multiple of different values
SELECT s.firstName, s.lastName, sum(correct) AS score
FROM student s
JOIN test t ON s.id = t.studentid
WHERE t.testType in ( 1,2,3,4 )
GROUP BY lastName, firstName
I think between clause can answer your question - http://www.tutorialspoint.com/mysql/mysql-between-clause.htm
where t.testType between 1 and 4
SELECT s.firstName, s.lastName, b.score, c.score2
FROM student s
JOIN (
SELECT s.id,s.firstName, s.lastName, sum(correct) AS score FROM student s JOIN test t ON s.id = t.studentid WHERE t.testType = 1 GROUP BY lastName, firstName
) b ON (s.id = b.id)
JOIN (
SELECT s.id,s.firstName, s.lastName, sum(correct) AS score2 FROM student s JOIN test t ON s.id = t.studentid WHERE t.testType = 2 GROUP BY lastName, firstName
) c ON (s.id = c.id)
GROUP BY lastName, firstName
I just used a bunch of JOIN statements. It works. Just doesn't show anything if either value is 0.

Extracting data from multiple tables in mysql

My problem is to write a SQL query to return the names of all teachers who have taught a course where at least 2 students received a B- or better in the course.
My tables are:
Courses(id, name, teacher_id)
Grades(student_id, course_id, grade)
Students(id, name, email, password)
Teachers(id, name)
I used the following query:
SELECT * FROM grades JOIN teachers WHERE grades.grade = 'B-'
But shows all teacher like
You can use exists() for that to check if for each teacher exists a course that had more then 2 'b-' or better
So your query should be:
SELECT * FROM Teachers t
WHERE EXISTS(SELECT c.teacher_id from Courses c
inner join grades g ON c.id= g.course_id
where t.id = c.teacher_id and g.grade in('B-','B','A-','A','A+')
group by c.teacher_id having count(*) > 1)
This should work:
Select distinct Teachers.name from Courses join Teachers on Courses.teacher_id = Teachers.id where Courses.id in (Select course_id from (Select course_id, count(student_id) as 'total' from Grades where grade = 'B-' or grade = 'B' or grade = 'B+' or grade = 'A-' or grade = 'A' group by course_id) a where a.total > 1)

How to find result of two table as unique when count of column equal one or two?

I have two table , one name of student and other one have lesson of student , I need to find student with have two or one lesson .
table 1 :(students)
id , name , family , birth , mobile
table 2 : (lessons)
id , studentID , name
and my code is
SELECT t.* FROM students AS t LEFT JOIN lessons AS tr ON t.id = tr.userID WHERE count(tr.*) = 1
This is your query:
SELECT students.name, COUNT(studentID) AS CANT FROM students, lessons WHERE students.id = studentID GROUP BY studentID HAVING CANT = 1 OR CANT = 2
Try this
SELECT s.id , s.name , family , birth , mobile FROM student s, lessons l WHERE s.id = l.studentID AND (SELECT COUNT(*) FROM lessons WHERE studentID = student.id) as totalLessons BETWEEN 1 AND 2 GROUP BY s.id

Join on specific key not working

I have four tables like this:
schoolyear (id)
student (id, schoolyear_id)
test (id)
grade (id, test_id, student_id, score)
A student is associated with a schoolyear (through fk), and a grade is associated with a test and a student through fk's.
I want all students for a particular schoolyear to be returned regardless, and join the test score for the student along with all other fields from the student table if it exists. If not, the score field should be null. Here is what I have:
SELECT *, `student`.`id` as `studentid`
FROM `student`
LEFT JOIN `grade` ON `grade`.`student_id` = `student`.`id`
WHERE `student`.`schoolyear_id` = ?
There's nothing in my current statement telling it a particular test yet, but that's what I want.
SELECT *, `student`.`id` as `studentid`, t.*
FROM `student`
LEFT JOIN `grade` ON `grade`.`student_id` = `student`.`id`
LEFT JOIN `test` t ON `t`.`id` = `grade`.`test_id`
WHERE `student`.`schoolyear_id` = ?
and test_id = ?
Just add the conditional to the ON clause. This will ensure that students stay included, even if there's no grade for that test.
SELECT g.*, s.id
FROM Student s
LEFT JOIN Grade g
ON g.student_id = s.id
AND g.id = ?
WHERE s.schoolyear_id = ?

Categories