SQL Query conversion to Django ORM - sql

select
l.student_id,
SUM(l.sum_result)
FROM
(
SELECT
w.student_id,
w.subject_id,
r.total as sum_result
from
Student w
INNER JOIN (
SELECT
COUNT(r.id) as total,
r.subject_fk_id
from
Result r
GROUP BY
r.subject_fk_id
) r ON w.subject_id = r.subject_fk_id
) l
GROUP BY
student_id
The tables are:
Student
-------------
-> id(PK)
->student_name
->student_email
Subject
--------------
-> id(PK)
-> subject_name
Results
---------------
->id (PK)
->subject_fk(FK to subject table)
->date
there is one many to many table for student and subject
Student_Subject
->id(PK)
->Student_id(FK)
->Subject_id(FK)
I want to convert this SQL query to Django ORM
I need to retreive the total number of results for a Student. I need to write this query in Django
ORM without for loops. Thank you in advance

your query missing a relationship part , also you can simplify your query to this :
select s.student_id,count(r.id)
from students s
Join student_subject ss
on ss.studentid = s.studentid
join subject sb
on sb.subject_id = ss.subject_id
join result r
on r.ssid = ss.id
group by s.student_id
so now I think you can write equivalent ORM yourself easily , right ? ;)

Related

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

How to query for many to many relationship in Sql Server

Here is my tables
My question is How to get CourseNames for a specific student id
I tried this but didn't work
select Course.CourseName from Course
where Course.CourseId in (
select Student.studentname ,StudentCourse.CourseId from Student inner join StudentCourse
on Student.StudentId = StudentCourse.StudentId
where Student.StudentId = 1)
You can forget my query because i am new in SQL Server just tell me what exactly developers do in SQL Server real-world to get course names of a specific student
As you said you want to know the approach this is just basic viewpoint
1) We want to look at CourseName's.
SELECT CourseName FROM Course
2) One Student may have more than one Courses.
3) So we have one more table which is StudentCourse to achieve this.
4) We have to look CourseName's ID'S in this table
SELECT CourseID FROM StudentCourse
5) to find which students(X is a number you seach for) takes those courses.
WHERE StudentID = X
6) If we look them together, we now have all CourseName's via step 1. But we don't want all CourseName's and we have all CourseID's which X numbered student takes. So if we get them together, now we will just select CourseName's which X takes.
WHERE CourseID IN
7) So our final result is
SELECT CourseName FROM Course WHERE CourseID IN
(SELECT CourseID FROM StudentCourse WHERE StudentID = X)
Check this or this one to see how it works.
I'm using left joins just in case your student doesn't have any courses assigned, otherwise, if you use inner joins, you'll get no results;
SELECT
s.StudentID
,s.StudentNam
,sc.CourseID
,c.CourseName
FROM Student s
LEFT JOIN StudentCourse sc
ON s.StudentID = sc.StudentID
LEFT JOIN Course c
ON sc.CourseID = c.CourseID
WHERE s.StudentID = 1
try this:
select CourseName from Course
where CourseId in
(select CourseId from StudentCourse
where StudentId = 1)

SQL query returns student id, course section id, and grade when section id 1000

Using Oracle Apex Browser, image of database
http://imgur.com/a/Hhblp#0
select s_ID, c_sec_ID, grade
from s_ID.ID, c_sec_ID.csID, grade.ID, grade.csID
where c_sec_ID = 1000
^ All I think of and I'm not sure if I'm suppose to join them together or group them either.
You have to join these tree tables COURSE_SECTION, ENROLLMENT and STUDENT to get desired output. Put INNER JOIN on three tables and add
Where Clause to filter records.
You can try this
SELECT S.s_ID, C.c_sec_ID, E.grade
FROM COURSE_SECTION C INNER JOIN ENROLLMENT E ON C.C_SEC_ID = E.C_SEC_ID
INNER JOIN STUDENT S ON S.S_ID = E.S_ID
WHERE C.C_SEC_ID = 1000

Writing two queries (sort students and cities according to average grades)

I have three tables:
1) Students: studentID (KEY), name, surname, address
2) Exams: examID (KEY), examName
3) Grades: studenID (KEY), examID(KEY), grade
How to write SQL query to show the best students (for example those with average grade above 9)?
How to write SQL query to rank Cities (column address) according to the average grade of their students?
I'm a system engineer, working with Unix and Linux systems and I am new in SQL, I only know about SQL basics, and I was trying to do this for past three days, with no success, so please help me. I presume it's not a complex thing for one who's experienced in SQL. Thanks a lot.
your first query to show the best students :
SELECT student.surname, students.surename, students.address
FROM
students INNER JOIN Grades ON Grades.StudentID=Students.StudentID
INNER JOIN Exams ON Grades.examID=exams.examID WHERE Grades.grade=
(SELECT MAX(grade) FROM Grades WHERE examID=exams.examID)
your second query to rank cities:
SELECT students.address
FROM
students INNER JOIN Grades ON Grades.StudentID=Students.StudentID
INNER JOIN Exams ON Grades.examID=exams.examID order by grades.grade DESC
Refer the fiddle here:
LINK 1 : http://sqlfiddle.com/#!4/ab4de6/19
LINK 2 : http://sqlfiddle.com/#!4/ab4de6/32
Below Queries should help you in Oracle:
--List of Students having Average grade >=9
SELECT S.studentID, S.NAME, S.SURNAME, S.ADDRESS, A.AVG_GRADE FROM
STUDENTS S JOIN
(
SELECT studentID, AVG(GRADE) AVG_GRADE FROM GRADES
GROUP BY studentID
) A
ON S.studentID = A.studentID
AND A.AVG_GRADE >=9
ORDER BY A.AVG_GRADE, S.studentID;
--------------------------------------------------------------------
--- Rank cities
SELECT A.ADDRESS, A.AVG_GRADE, ROWNUM RANKING FROM
(
SELECT S.ADDRESS, AVG(G.GRADE) AVG_GRADE FROM
STUDENTS S JOIN GRADES G
ON S.STUDENTID = G.STUDENTID
GROUP BY S.ADDRESS
ORDER BY 2 DESC
) A;
You need to know about the following concepts.
INNER QUERY / SUB QUERY
JOINS
AGGREGATE FUNCTIONS (Average Calculations)
GROUP BY
ORDER BY
ROWNUM

sql foreach without using cursor

I have a table "Student" in sql with a structure:
StudentId FirstName LastName
1 X Y
....
AND a table of Languages ,its structure:
LanguageId Name
1 English
2 Mandarin
3 Spanish
.....
and a relationship table StudentLanguage (languages spoken by a student)
StudentId LanguageId
1 1
1 3
2 1
2 2
from my asp.net page i want to filter students by spoken languages using checkboxes.
for example,when i check English,Madarin i want to have students speaking both English and Madarin
When i check French,Spanish ,English ==>Get students speaking French,AND English,AND Spanish.
to do that i pass a table of Languages paramter called #LanguageTable(LanguageId smallint) to a stored procedure.
how can i use this table to get the students without using a cursor.
I have tried with CTE but no result.
Try this:
select s.StudentId,s.FirstName,s.LastName
from Stundent s
join StudentLanguage sl on s.StudendID=sl.StudentId
join #LanguageTable on sl.LanguageId=#LanguageTable.LanguageId
group by s.StudentId,s.FirstName,s.LastName
having count(*)=(select count(*) from #LanguageTable)
You need relational division.
SELECT s.StudentId, s.FirstName, s.LastName
FROM Student s
WHERE NOT EXISTS(SELECT *
FROM #LanguageTable l
WHERE NOT EXISTS(SELECT *
FROM StudentLanguage sl
WHERE sl.LanguageId = l.LanguageId
AND sl.StudentId = s.StudentId))
I haven't tested this but:
SELECT s.StudentId, s.FirstName, s.LastName
FROM Student s
INNER JOIN StudentLanguage sl ON sl.StudentId = s.StudentId
INNER JOIN #Language l ON l.LanguageId = sl.LanguageId
GROUP BY s.StudentId, s.FirstName, s.LastName
HAVING Count(*) = (SELECT COUNT(*) FROM #Language)