Recursive sql query n to n in SQLite - sql

I have a database table like that
Table student
_______________
id_student int (PK)
student_name VARCHAR
and I have a recursive loop:
A student can oversee many students, and a student can be overseen by many students
so a new table:
Table oversee
________________
id_student pk, fk
id_overseen pk, fk
date date
the problem is that I want to get the list that I have
I made an sql query:
with
sr1 as ( select s.student_name as over from student s, oversee o where o.id_student = s.id_student),
sr2 as (select s.student_name as overseen from student s, oversee o where o.id_overseen = s.id_student)
select distinct * from sr1, sr2;
the problem is that's the query returns the wrong answers
I mean if we have two lines in the table, it will return 4 lines.
I want to get every student with his overseen:
Student | overseen.
Someone has any idea please?
Thanks.

I want to get a table with student | overseen | date
SELECT s.student_name AS student
, s2.student_name AS overseen
, oversee.date
FROM student s
JOIN oversee ON oversee.id_student = s.id_student
JOIN student s2 ON s2.id_student = oversee.id_overseen

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

Native Query to Select records to only contain specific ids

I am in the process of implementing an advanced search in my application. I'm sort of new with Oracle and JPA. The database structure has a many-to-many relationship (ERD) with an intermediate table that contains StudentID and CourseID.
I'm trying to return rows of students that have the list of classes/courses.
Basically, I want the results of
SELECT DISTINCT s.* FROM STUDENT s
INNER JOIN STUDENT_COURSE sc ON s.StudentID = sc.StudentID
INNER JOIN COURSE c ON c.CourseID = sc.CourseID
WHERE ( c.CourseID IN (SELECT DISTINCT CourseID FROM STUDENT_COURSE WHERE CourseID = 'A01') AND c.CourseID IN (SELECT DISTINCT CourseID FROM STUDENT_COURSE WHERE CourseID = 'A02'));
which returns the records of students that have both courses 'A01' and 'A02'.
ID
Age
Grade
1
...
...
4
...
....
9
...
....
with courses
Courses
A01,A02
A01,A02,A03,X02
A01, A02, A03
The goal is to get a similar result using Spring Data JPA. And make it more general to select any number of Course Ids.
I've tried
#Query(value="SELECT DISTINCT s.* FROM STUDENT s "
+"INNER JOIN STUDENT_COURSE sc ON s.StudentID = sc.StudentID "
+"INNER JOIN COURSE c ON c.CourseID = sc.CourseID "
+"WHERE ( s.STUDENTID IN (SELECT DISTINCT STUDENTID FROM STUDENT_COURSE WHERE CourseID =:courseIds)",nativeQuery=true))
public List<Student> advancedSearch(#Param("courseIds") String courseIds);
One example, The courseIds field contain "A01,A02". The result would be empty.
I've looked at examples where people use IN. When I tried it, it would return records of the student have courses AO1 OR A02 OR Both.
DON'T WANT THIS
ID
Age
Grade
2
...
...
3
...
....
8
...
....
With Courses
CourseID
A01,A03
A01, X01
A02
I want records of students that have both A01 AND A02 as shown in the other table.
My guess is that the query you want is
select s.name /* note this column doesn't appear in your ERD */
,s.age
,s.grade
from student s
join student_course sc
on s.studentID = sc.studentID
where sc.courseID IN ('A01', 'A02')
group by s.name /* again, this column isn't in your ERD */
,s.age
,s.grade
having count(sc.courseID) = 2
That doesn't produce the output table you say you want. But neither does the query you posted. This will return all the students that have taken both courses (you could add a distinct to the having clause if the data model were to change to allow a student to take a course multiple times). It won't give you the list of all courses that student has taken as a comma-separated list. But the query you posted doesn't return any course information either.
If this isn't what you are looking for, it would be really helpful to update your question with
The DDL for your schema in text form (so we can run it) rather than as an image
The DML to insert whatever sample data you want
The actual results you'd want the query to return (since there is a conflict between what the query you posted returns, the table of data you say you want, and the descriptive text of what you are trying to accomplish, it is confusing to try to figure out which is right).

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).

ICannot figure out how to run queries for student

Here is my code that I created for each of the tables, not sure how to join the tables to calculated the gpa's??
CREATE TABLE Student(SSN NUMBER(4) NOT NULL,
SName VARCHAR(20) NOT NULL,
Major VARCHAR(4),
Because grade and SSN are in the grades table, you dont need to join and can get the average grade like this:
This gives the average grade per student, ordered by the grade:
SELECT AVG(g.Grade), g.SSN
FROM Grade g
group by g.SSN
order by AVG(g.Grade)
If you wanted average grade per course it would look like this:
SELECT AVG(g.Grade), g.cno
FROM Grade g
group by g.cno
order by AVG(g.Grade)
However, if you need more information from student, you'd need to join to the student table:
select *
from (
SELECT AVG(g.Grade) as average_grade, g.SSN
FROM Grade g
group by g.SSN) a
inner join Student s on a.ssn = s.ssn

Sql Query Join in Oracle

I have Parent table and multiple child tables with foreign key constraint.
School Table
School ID EduDetails Genders Address_id EDUTYPE
1 2 M 3 FGN
And the child tables like
Education Details
EDU ID EducationType
2 Online
AKA Name
School Id AKA Name
1 Test School
1 School Test
Gender Table
Gender ID Gender Desc
M Male
I am using Left outer join for the parent and school table to fetch the results.
But My issue is, If AKA table has 5 counts matching the school Id and Gender table has only 1 records for that school Id.
So the results comes with 5 duplicate rows with school Information and also other child table information.
Is there any workaround to fix this issue. I tried using subquery and row_number over by function. But it is not working for me. Can anybody help me to solve this issue.
Thanks in advance for your time in looking this issue.
My required output should be like this
School_id AKA Name GenderDesc EductaionType
1 Test School Male Online
1 School Test
So I need to have Null values for the not matching records.
Since you want all the records in the AKA Name table, I've joined on that getting a Row_Number for each row. Then using that Row_Number, LEFT JOIN on the other tables.
SELECT S.SchoolId,
SA.AKAName,
G.GenderName,
ED.EducationType
FROM School s
JOIN
(SELECT SchoolId,
AKAName,
ROW_NUMBER() OVER (PARTITION BY SchoolId ORDER BY AKAName) rn
FROM SchoolAKA
) SA ON S.SchoolID = SA.SchoolId
LEFT JOIN
(SELECT EDUID,
EducationType,
ROW_NUMBER() OVER (ORDER BY EducationType) rn
FROM EduDetails
) ED ON S.EDUID = ED.EDUID AND SA.rn = ED.rn
LEFT JOIN
(SELECT GenderId,
GenderName,
ROW_NUMBER() OVER (ORDER BY GenderName) rn
FROM Genders
) G ON S.GenderId = G.GenderId AND SA.rn = G.rn
Here is the SQL Fiddle.
And here are the results:
SCHOOLID AKANAME GENDERNAME EDUCATIONTYPE
1 School Test Male Online
1 Test School (null) (null)