ICannot figure out how to run queries for student - sql

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

Related

How to get average of values in T-SQL from specific table and join it's result with other one?

So basically, I have two tables:
STUDENT {IdStudent Int (PK), IndexNr Varchar(10), Year Int, Name Varchar(32), Surname Varchar(64)}
MARK {IdMark Int (PK), IdStudent Int (FK), Value Int, Subject Varchar(32)}
and as a first part of this exercise I need to run over them and grab all students from specific year (let's 2) and write out their average mark separately for each one of them.
I wanted to do this through cursor but I'm having troubles with it.
Mainly because I can't properly select these average marks using inner join.
For example I would like to return IndexNr and AverageMark.
You can do it by joining the tables and then use group by each student:
select
s.idstudent, s.name, s.surname
avg(m.Value) AverageMark
from student s inner join mark m
on m.idstudent = s.idstudent
where s.year = 2019
group by s.idstudent, s.name, s.surname
but shouldn't the table mark also contain a year column?
I think GROUP BY is what you're looking for: https://www.w3schools.com/sql/sql_groupby.asp
SELECT
s.Name
,s.Year
,AVG(m.Value) as Mean
FROM Student s
JOIN Mark m ON m.IdStudent = s.IdStudent
GROUP BY
s.Name
,s.Year
If you want the average over all students, then you want one row. Don't use group by.
You also need a where for the year condition:
SELECT AVG(s.Value) as Mean
FROM student s
WHERE s.year = ? -- whatever year you want

Recursive sql query n to n in SQLite

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

Write a sql to retrieve names of all students with S grade in all the courses he/she has attempted?

I've been practicing DBMS queries and I'm stuck with the following sql query:
Write a sql to retrieve names of all students with S grade in all the courses he/she has attempted?
Following are my tables and code
create table COURSE
(
cId int primary key,
cName varchar(30),
credits int not null
);
create table student
(
usn int primary key,
sname varchar(20),
dno int
);
create table RESULT
(
SUsn int,
CCode int,
Grade char,
primary key(SUsn,CCode)
);
Code:
select S.sname
from student S inner join result R on S.usn = R.susn
where grade = 'S'
group by S.usn,S.sname
having count(*) in (
select count(*) from result
group by susn
);
May I know where I'm going wrong? Please help me.
You are actually overcomplicating the question. You are answering the question about students who have gotten an "S" in all courses. For this question, you only need to see if any grades are not "S":
select S.sname
from student S inner join
result R
on S.usn = R.susn
group by S.usn, S.sname
having sum(case when grade <> 'S' then 1 else 0 end) = 0;
Please try the following...
SELECT usn,
sname
FROM ( SELECT usn AS usn,
sName AS sName,
SUM( CASE
WHEN Grade = 'S' THEN
1
ELSE
0
END ) AS sCount,
COUNT( * ) AS totalCount
INNER JOIN result on student.usn = result.SUsn
FROM student
GROUP BY usn
) AS usnCounter
WHERE usnCounter.sCount = usnCounter.totalCount
ORDER BY sname;
This statement starts by selecting each usn and sname from student along with a count of courses that a student has undertaken where their Grade equals S, and a count of all courses that a student has undertaken, irrespective of their Grade.
The usn and sname is then chosen from the list so generated WHERE the count of Grade values for a student that equal S equal the total count of courses for that student.
I have included usn in the results so as to uniquely identify students as it can not be safely assumed that no two students will have the same value for sname.
If you have any questions or comments, then please feel free to post a Comment accordingly.

SQL Select entries where none of the entities have a value in a particular column

I have a table of data which has students and their subject results in it. The students will appear multiple times, once for each subject they have a result for.
**tableID,studentID,lastName,firstName,subject,grade**
1,1a,Student1,Name1,English,A
2,1a,Student1,Name1,Maths,A
3,1a,Student1,Name1,Science,A
4,2a,Student2,Name2,English,A
5,2a,Student2,Name2,Maths,B
6,2a,Student2,Name2,Science,A
7,3a,Student3,Name3,English,A
8,3a,Student3,Name3,Maths,A
Using Microsoft Access SQL, how can I select only the students who have received an A for all of their subjects? E.g. In the above table, I only want to select all instances of Student1 and Student3, I don't want Student2 as they have not received all A's.
Get all students with grade A except students with any other grade
SELECT
studentID,lastName,firstName
FROM
(SELECT
studentID,lastName,firstName
FROM
result
WHERE
grade = 'A'
GROUP BY
studentID,lastName,firstName) GradeA
LEFT OUTER JOIN
(SELECT
studentID,lastName,firstName
FROM
result
WHERE
grade <> 'A'
GROUP BY
studentID,lastName,firstName) GradeOther
ON GradeA.studentId = GradeOther.StudentID AND GradeA.LAstName = GradeOther.LastName AND GradeA.FirstName = GradeOther.FirstName
WHERE
GradeOther.StudentID IS NULL
One way is using GROUP BY and HAVING:
select StudentId
from t
group by StudentId
having max(grade) = min(grade) and max(grade) = 'A';
I was able to get the results I want by using a sub-query:
SELECT studentID, lastName, firstName
FROM table
WHERE grade = "A"
AND studentID NOT IN (SELECT studentID FROM table WHERE grade <> "A" GROUP BY studentID)
GROUP BY studentID, lastName, firstName
This seems to exclude all students who received a result other than an A.

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