Mapping table join query - sql

I have three tables as follows,
student
category
student_category
Student table has the following columns:
studentid, student name, studenttype
Category table has the following tables:
categoryid, categoryname, ..
student_category table has the following columns:
id, studentid, categoryid
Now I have 2 input parameters categoryid and studenttype so now I need to get the all the student details which are associated with respective categoryid and whose student type is studenttype
I tried as follows which is not giving correct result,
SELECT
s.*
FROM
student s
JOIN
student_category sc ON sc.categoryid = 1;
Also I also need to filter student whose studenttype is 'someinput'
I am working on PostgreSQL. Any suggestions please

You should add a where clause and also use the appropiate join condition.
SELECT s.*
FROM student s
JOIN student_category sc ON sc.studentid = s.studentid
where s.studenttype = 'studenttype' --or your desired value
and sc.categoryid = 1

Related

SQL select - Get all from exams table where examId exists in subjects table, for all subjects that exist in students table for desired studentId

I have three tables: exams, subjects and students.
Students table has foreign key subjectId and Subjects table has foreign key examId.
I need to retrieve all exams for desired studentId. So I need sql select that will pick up all subjects for that studentId, and pick up all exams for all these subjects.
So pseudo code is something like:
SELECT * FROM exams
WHERE id IN (SELECT examId FROM subjects
WHERE id IN (SELECT subjectId from students
where id === desiredId))
Why are you using subqueries and just not inner join?
Try with this:
Select X.* From exams X
Inner join subjects S on S.examId = X.id
Inner join students T on T.subjectId = s.Id
Where T.id =#yourStudentId

PostgreSQL: How do I get data from table `A` filtered by a column in table `B`

I want to fetch all parents that have kids in a specific grade only in a school.
Below are trimmed down version of the tables.
TABLE students
id,
last_name,
grade_id,
school_id
TABLE parents_students
parent_id,
student_id
TABLE parents
id,
last_name,
school_id
I tried the below query but it doesn't really work as expected. It rather fetches all parents in a school disregarding the grade. Any help is appreciated. Thank you.
SELECT DISTINCT
p.id,
p.last_name,
p.school_id,
st.school_id,
st.grade_id,
FROM parents p
INNER JOIN students st ON st.school_id = p.school_id
WHERE st.grade_id = 118
AND st.school_id = 6
GROUP BY p.id,st.grade_id,st.school_id;
I would think:
select p.*
from parents p
where exists (select 1
from parents_students ps join
students s
on ps.student_id = s.id
where ps.parent_id = p.id and
s.grade_id = 118 and
s.school_id = 6
);
Your question says that you want information about the parents. If so, I don't see why you are including redundant information about the school and grade (it is redundant because the where clause specifies exactly what those values are).

SQL query with more than 2 tables

I'm doing an exercise on ORACLE SQL.
Currently I got 3 tables.
Student values = "student_id ,name"
Subjects values = "subject_id, name"
Scores values = "score, student_id, subject_id"
I'm trying to retrieve the following information from my database.
Name of student, Name and id of the subject and finally the score that has the student_id "34560".
SELECT scores.score,
scores.subject_id,
student.name,
subject.subject_id,
subject.name
FROM scores
INNER JOIN students
ON scores.student_id = '34560'
INNER JOIN subject
ON /* and here's where i'm lost*/
Is there a way to put all together from the first part of the query where I call the list of students with student_id = "34560" and then query that list to see if it matches with the subject_id?
Use in operator for list of student id
SELECT sc.score, sc.subject_id,
st.name, sb.subject_id, sb.name
FROM scores sc
INNER JOIN students st
ON sc.student_id = st.student_id
INNER JOIN subject sb
ON sc.subject_id=sb.subject_id
where sc.student_id in ('34560','add_anotherstudentid','add_anotherstudentid') //you can add multiple student id

SQL query - list of items in one table not in another

I need some help with a SQL query. I have a table of courses and a table that contains user id and course id, denoting courses that user has taken (might not have taken any; no entry in that table for that user id).
I need a query to return the list of courses not taken.
Course Category table
CategoryID
Caegory
Courses table
CourseID
CategoryID
CourseName
...
UserCourse table
UserID
CourseID
you can use not exists
Select *
From Courses c
Where Not Exists (Select 1 From UserCourse uc Where uc.CourseID = c.CourseID)
This will just list the course
select *
from Courses C
Left join CourseCategory cc on
cc.CategoryID = c.CategoryID
where CourseID not in (Select CourseID from UserCourse where UserID = 14)
what i need is for a given user id and course category, what courses within that category have not been taken by this user
(This should have been in the request by the way.)
So:
Select from courses.
Limit to the desired category.
Limit to courses not in the set of courses taken by the user.
The query:
select *
from courses
where categoryid = 123
and courseid not in (select courseid from usercourse where userid = 456);
Another way of writing same query, which will perform faster.
select C.CourseID,C.CategoryID
from Courses C
Left join CourseCategory cc on
cc.CategoryID = c.CategoryID
left join UserCourse uc
on C.CourseID=uc.CourseID
where uc.CourseID is null

Find the minimum value of a SQL table attribute and create a new table of attributes?

I have three SQL tables. The first is SCUBA_CLASSES with attributes CLASSID and CLASSNAME. Second is a table called STUDENTS with attributes STUDENTID and AGE. Third is a table TAKES_CLASS with attributes STUDENTID and COURSEID.
How do I create a new table that displays the CLASSID and CLASSNAME of the youngest student in the group?
I have:
CREATE TABLE YOUNGEST_STUDENT_ENROLLMENT
SELECT SCUBA_CLASSES.CLASSID AS CLASSID, SCUBA_CLASSES.CLASSNAME AS CLASSNAME
FROM SCUBA_CLASSES, STUDENTS, TAKES_CLASS
WHERE MIN(STUDENTS.AGE)
Not sure what to do from here. I have to find the youngest student and output the CLASSID and CLASSNAME of all the classes they are enrolled in.
It would seem a VIEW would be a better fit than a table. The view will update automatically when new students are enrolled;
CREATE VIEW YOUNGEST_STUDENT_ENROLLMENT AS
WITH cte AS (
SELECT SC.CLASSID, SC.CLASSNAME, S.NAME, S.AGE,
ROW_NUMBER() OVER (PARTITION BY SC.CLASSID ORDER BY AGE) RN
FROM SCUBA_CLASSES SC
JOIN TAKES_CLASS TC ON SC.CLASSID = TC.CLASSID
JOIN STUDENTS S ON S.STUDENTID = TC.STUDENTID
)
SELECT CLASSID,CLASSNAME,NAME,AGE FROM cte WHERE RN=1;
This view will always contain the person with the lowest age per class. If you want it to contain only the lowest aged person no matter which class, you can remove the PARTITION BY SC.CLASSID clause.
An SQLfidde to test with.
Try this nested query:-
CREATE TABLE YOUNGEST_STUDENT_ENROLLMENT AS (
SELECT SCUBA_CLASSES.CLASSID AS CLASSID, SCUBA_CLASSES.CLASSNAME AS CLASSNAME
FROM SCUBA_CLASSES
WHERE SCUBA_CLASSES.CLASSID IN (SELECT TAKES_CLASS.CLASSID FROM TAKES_CLASS
WHERE TAKES_CLASS.STUDENTID IN (SELECT STUDENTS.STUDENTID FROM STUDENTS
WHERE STUDENTS.AGE IN (SELECT MIN(STUDENTS.AGE) as AGE FROM STUDENTS))));