MySQL query with AND and OR in WHERE clause - mysql

I am creating a student records search query. The school has three clubs (maths, english and science). What i want to do is to select student by the club they have joined in this order.
Student who are in
-- Maths Only
-- Maths and English only
-- Maths and Science Only
-- English Only
-- English and Science Only
-- Science Only
Student table (studentTB)
id | student_name | date_join
-----------------------------
1 | Daniel Addo | 2012-01-05
2 |David Polles | 2013-05-11
3 | Grace Amorno | ---------
4 | Zein Akill | ---------
Club table (studentCLUB)
id | studentID | club
----------------------
1 | 1 | maths
2 | 1 | science
3 | 2 | science
4 | 2 | english
5 | 3 | science
6 | 4 | maths
7 | 4 | science
8 | 4 | english
SELECT *
FROM studentTB
INNER JOIN studentCLUB
ON studentTB.id = studentCLUB.studentID
WHERE (club = 'maths') OR (club = 'science') OR (day = 'english')
GROUP BY studentTB.id
This is what i have so far and it is selecting student when they fall within one of the club. But when i change the OR to AND it gives me null.
I will be glad if anyone can help me. Thank you

So it you need to find students who belongs to all the given club you can do as below. It will check the students having all the given 3 clubs.
SELECT *
FROM studentTB
INNER JOIN studentCLUB
ON studentTB.id = studentCLUB.studentID
WHERE
club in ('maths','science','english')
GROUP BY studentTB.id
having count(*) = 3

SELECT * FROM studentTB
WHERE EXISTS(SELECT * FROM studentCLUB
WHERE studentTB.id = studentCLUB.studentID)

Related

Multiple SELECT statements from different tables

I have two independent tables: 'Clients' and 'Country'.
Country Table:
IdCountry Country
1 SPAIN
2 PORTUGAL
Clients Table
IdClient Entity IdCountry
1 Adam Alves 2
2 Peter Smith 2
3 David Ramos 1
4 Rafael Castro 1
I would like to add a new client into 'Clients' table but using the information from 'Country' table like this:
INSERT INTO Clients(IdClient, Entity, Country)
SELECT max(IdClient) + 1, '--New--' FROM Clients,
SELECT IdCountry FROM Country WHERE Country = 'SPAIN'
I would like to have this INPUT:
IdClient Entity IdCountry
5 --New-- 1
But if I run this query, it doesn't work. Could anybody help me, please?
COMMENTS: I prefer don't use autoincrement option.
Thank you very much.
Wardiam
You can do it like this:
INSERT INTO Clients(IdClient, Entity, Country)
SELECT
(SELECT MAX(IdClient) + 1 FROM Clients),
'--New--',
(SELECT IdCountry FROM Country WHERE Country = 'SPAIN')
See the demo.
Results:
| IdClient | Entity | Country |
| -------- | ------------- | ------- |
| 1 | Adam Alves | 2 |
| 2 | Peter Smith | 2 |
| 3 | David Ramos | 1 |
| 4 | Rafael Castro | 1 |
| 5 | --New-- | 1 |

am new to mysql queries, i want to join these four tables, count the number of students who belong to each school and group them by school name

am new to mysql queries, i want to join these four tables i want to count the number of students who belong to each school and group them by school name.
then i want to find the number of male and female students per school
Note:considering there is actual data in the tables
here is what am trying to do but its not giving actual results
SELECT COUNT(studentid) AS totalStudentsRegistered,
s.schoolid,s.schoolName
FROM student s,course c,program p,school s
WHERE s.cousreid = c.courseid
AND c.programid= p.programid
AND p.schoolid= s.schoolid
GROUP BY s.schoolName
-----------------
table A (student)
-------------------------------------------------------------
studentid | Name | age | gender |courseid
-------------------------------------------------------------
1 | joe goe | 23 |male |1
2 |sands sou | 20 |female |2
3 |marry goe | 23 |male |1
4 |jane mand | 20 |female |2
-------------------------------------------------
table b (courses)
-------------------------------------------------------------
courseid | couseName | programid
-------------------------------------------------------------
1 | Math | 1
2 | science | 2
-------------------------------------------------------------
table c (programs)
-------------------------------------------------------------
programid | programName | schoolid
-------------------------------------------------------------
1 | Degree | 1
2 | Diploma | 2
-------------------------------------------------------------
table c (school)
-------------------------------------
schoolid | schoolname
-------------------------------------
1 | school of math
2 | school of scince
-------------------------------------
You can use such a query
SELECT sc.schoolid, sc.schoolName,
COUNT(st.studentid) AS totalStudentsRegistered,
SUM(st.gender = 'male') AS totalmalestudent,
SUM(st.gender = 'female') AS totalfemalestudent
FROM student st
JOIN courses c ON st.courseid = c.courseid
JOIN programs p ON c.programid = p.programid
JOIN school sc ON p.schoolid = sc.schoolid
GROUP BY sc.schoolid, sc.schoolName
where
add all non-aggregated column into the GROUP BY list
use explicit JOIN syntax among tables instead of comma-seperated old one.
Here the default JOIN(INNER) is used. That might be replaced by LEFT
JOIN depending on the data which might be unmatched for the ID
columns on the JOIN conditions.

Getting multiple rows as a single row in MySQL

I have a basic multi-school management system that I am working on for fun in order to learn querying from a MySQL database.
I am doing a number of joins from tables such as students, schools,student_grade, grade_school etc. I now want to get a list of all subjects the student has been assigned. Since there are multiple possible rows, I have a student_subject table to hold the student_id and then the subject_id values.
The following query gets me the student's name, and their grade:
SELECT a.id,a.firstnames,a.surname,d.gradename
FROM students a
LEFT JOIN student_grade b ON a.id=b.studentid
LEFT JOIN grade_school c ON c.id=b.gradeid
LEFT JOIN grades d ON c.gradeid=d.id
WHERE a.schoolid=? AND b.gradeid=? ORDER by a.surname ASC
This results in each row returned to be the student's name and their grade, like this:
ID | Firstname | Surname | Grade
1 | John | Doe | 4
5 | Sarah | Marshall | 7
How can I get all the subjects the student is assigned and put them all in a column "subject_ids" to get a result as follows:
ID | Firstname | Surname | Grade | Subjects
1 | John | Doe | 4 | 5,54,2,56
5 | Sarah | Marshall | 7 | 2,4,12,17
My table structures are as follows:
Table `students`
id | firstnames | surname | schoolid
Table `student_grade`
id | studentid | gradeid
Table `grade_school`
id | gradeid| schoolid
Table `grades`
id | gradename|
Table `student_subject`
id | studentid| subjectid
4 | 1 | 5
5 | 1 | 54
6 | 1 | 2
7 | 1 | 56
8 | 5 | 2
9 | 5 | 4
10 | 5 | 12
11 | 5 | 17
Try this:
SELECT a.id,a.firstnames,a.surname,d.gradename, GROUP_CONCAT(s.subjectid)
FROM students a
LEFT JOIN student_grade b ON a.id=b.studentid
LEFT JOIN grade_school c ON c.id=b.gradeid
LEFT JOIN grades d ON c.gradeid=d.id
LEFT JOIN student_subject s ON s.studentid=a.id
WHERE a.schoolid=? AND b.gradeid=? ORDER by a.surname ASC
also check this or this
The GROUP_CONCAT() function will do what you want here.
This question is a dup of Can I concatenate multiple MySQL rows into one field?

Retrieve Columns from Relational Database at Once

In order to simplify the problem, let's assume this is for a school database, and we have 3 tables. In this school the student can participate in multiple courses which have multiple lessons, and we store in the DB the information about the available courses, each course lessons and which courses and lessons the student is currently studying.
Table courses has 2 columns, cs_id and cs_name. Table lessons has 3 columns, ls_course which stores the ID of the course the lesson is from, ls_number —a sequential number that identifies the lesson within the course— and ls_name. The last table students stores the student ID, st_id, the course ID and current lesson in that course, st_course and st_lesson. Some sample data:
courses
+-------+----------+
| cs_id | cs_name |
+-------+----------+
| 1 | Course A |
| 2 | Course B |
+-------+----------+
lessons
+-----------+-----------+--------------+
| ls_course | ls_number | ls_name |
+-----------+-----------+--------------+
| 1 | 1 | Lesson One |
| 1 | 2 | Lesson Two |
| 1 | 3 | Lesson Three |
| 2 | 1 | Lesson One |
| 2 | 2 | Lesson Two |
| 2 | 3 | Lesson Three |
+-----------+-----------+--------------+
students
+-------+-----------+-----------+
| st_id | st_course | st_lesson |
+-------+-----------+-----------+
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 2 | 2 | 2 |
+-------+-----------+-----------+
As you can see we currently have 2 students, and the student with ID 2 is currently taking 2 courses at once. In Course A, she is in the third lesson and in Course B, in Lesson Two. What I want is to retrieve the listing for the courses one student is currently in. But not as:
SELECT * FROM students WHERE st_id = 2;
This returns the filtered rows, but I'd like to retrieve the course and lesson ID and names for them. To get the course name column I'd do this:
SELECT s.*, c.cs_name
FROM students s, courses c
WHERE s.st_id = 2 AND s.st_course = c.cs_id
Which results in:
+-------+-----------+-----------+----------+
| st_id | st_course | st_lesson | cs_name |
+-------+-----------+-----------+----------+
| 2 | 1 | 3 | Course A |
| 2 | 2 | 2 | Course B |
+-------+-----------+-----------+----------+
The far I can get is:
SELECT s.*, c.cs_name, l.ls_name
FROM students s, courses c, lessons l
WHERE
s.st_id = 2 AND
s.st_course = c.cs_id AND
s.st_lesson = l.ls_number
But how can I retrieve the lesson ID and chapter to check for a match in the lessons table, is it possible at all? The result I want is:
+-------+-----------+-----------+----------+--------------+
| st_id | st_course | st_lesson | cs_name | ls_name |
+-------+-----------+-----------+----------+--------------+
| 2 | 1 | 3 | Course A | Lesson Three |
| 2 | 2 | 2 | Course B | Lesson Two |
+-------+-----------+-----------+----------+--------------+
This query is wrong:
SELECT s.*, c.cs_name, l.ls_name
FROM students s, courses c, lessons l
WHERE
s.st_id = 2 AND
s.st_course = c.cs_id AND
s.st_lesson = l.ls_number
You need also to match st_course to ls_course
SELECT s.*, c.cs_name, l.ls_name
FROM students s, courses c, lessons l
WHERE
s.st_id = 2 AND
s.st_course = c.cs_id AND
(s.st_lesson = l.ls_number AND st.st_course=l.ls_course)
I would also recommend using the current JOIN syntax, i.e.
SELECT s.*, c.cs_name, l.ls_name
FROM students s
JOIN courses c ON c.cs_id=s.st_course
JOIN lessons l ON (s.st_lesson=l.ls_number AND st.st_course=l.ls_course)
WHERE s.st_id = 2

Data from 2 tables

there are two tables:
TABLE cars
id | date
----------
1 | 2012-01-04
2 | 2012-01-04
3 | 2012-01-05
TABLE versions
id_car | year | author
-------------------------
1 | 2005 | John
1 | 2001 | Carl
2 | 2003 | Carl
2 | 2001 | John
3 | 2004 | Carl
3 | 2003 | John
I need to get all the information about cars with yesterday's date (2012-01-04) and information about their latest version if author is Carl.
So in this example I need to get:
2 | 2012-01-04 | 2003 | Carl
You want an inner join:
select
c.id,
c.date,
v.year,
v.author
from
cars c
inner join versions v on
c.id = v.id_car
inner join (
select
id_car,
max(year) as latestYear
from
versions
group by
id_car
) vmax on
c.id = vmax.id_car
and v.year = vmax.latestYear
where
v.author = 'Carl'
and c.date = '2012-01-04'
In this query, you're saying, "Grab me everything from cars where the date is 2012-01-04 and then find everything in versions where the id_car column is equal to my id column in cars. Oh, and only give me anything from versions where the author is Carl, but only where the year of the car is equal to the greatest year of the car that's available."