SQL, how to have the lowest average? - sql

I have the following database
Student (NumStu, Name, Surname, BirthDate, Street, PC, City)
Teach (CodeTeach, Label, Coef)
Exam (numexam, DateExam, Place, #CodeTeach)
Notation (#NumStu, #NumTeach, Note)
And I want to have the list of the students who have the lowest average in the teach of Computer Science.
How to do it?

Do you need to select all students sorted by teach in Computer Science or only 1 student with lowest grade? You should add more description.
If students are inserted in Student table and their teaching grades in table Teach should be something like that(I can help you correctly after you give more detailed description):
SELECT S.NumStu, S.Name, S.Surname, S.BirthDate, S.Street, S.PC, S.City, T.ComputerScience
FROM Student AS S
INNER JOIN Teach AS T
ON T.AssociatedColumn = S.AssociatedColumn
ORDER BY T.ComputerScience -- Here you order students list from lowest grade (ascending)

SELECT *
FROM Student, Notation
ON Student.NumStu = Notation.NumStu
WHERE Notation.Note =
(
SELECT MIN(AVG(Note))
FROM Notation
GROUP BY NumStu
)
Explanation: This request will show you everything from the tables Student and Notation, when Note will be equal to the Minimum of the Average of Note.
I am not certain it will work, waiting for feedback.
P.-S: Am french too

Related

SQL : Getting count of a column and then multiplying it with a column from another table

I have three tables in my database,
Students-has student id,
Instructors which has instructor id, course name and hourly pay.
Enrollment table which has student id, course name, instructor.
I need to write a query to get the max amount of money paid to an instructor. Somethings to consider
A student can enroll into multiple courses
An instructor can teach multiple courses (Instructor is paid the same for each course)
Multiple instructors can teach the same course.
I came up with the required tables to get the entries first.
select hourlyPay, ins_id, stu_id from Instructors, Enrollment where Enrollment.ins_id = Instructors.Instr_id group by hourlyPay,ins_ID,stu_id
This gives me the output:
My end goal is to multiply the hourly pay with the student count and get the maximum, Could somebody please help me do it? I want the student count per instructor multiplied with the hourly pay.
Since I don't know the data and complete requirement. You can try something below:
(This top 1 works in SQL Server). I think in Orcle you need try FETCH FIRST number ROWS ONLY;)
select top 1 ins_id,sum(hourlyPay) Pay
from(
select hourlyPay
, ins_id
, stu_id
from Instructors
Join Enrollment ON Enrollment.ins_id = Instructors.Instr_id
group by hourlyPay,ins_ID,stu_id
) a
group by ins_id
order by 2 desc

When using the WITH clause in SQL, I get more than one average for one value

I need to show every book whose reader's age is below the mean age.
The schema consists of these tables:
AUTHOR: ISBN, Name, Lastname;
BOOK: ISBN, Name, Publisher, Pages, Value, Year;
EXEMPLAR: Number, Taken (date), Returned (date), ISBN, Reader (reader's number), READER: Number (also reader's number, just named differently), ID number, Name, Lastname, Birthdate, Address.
I wrote the following code:
WITH Name_and_age (Age, Name, ISBN) as (SELECT age(birthdate) as Age, Book.ISBN, Name
FROM Reader
JOIN Exemplar on Reader.Number=Exemplar.Reader JOIN Book ON Book.ISBN=Exemplar.ISBN),
MeanAge (Average)
as (SELECT AVG(Age) as MeanAge FROM Name_and_age)
SELECT Age, MeanAge, Name, ISBN FROM Name_and_age, MeanAge
WHERE Age < MeanAge
But for some books the result displays 2 or 3 different age averages. The total number of unique books is 7, however the result gives me 10 rows. Any ideas? Thank you in advance!
You say, I need to show every book whose reader's age is below the mean age.
Your code includes this:
SELECT Age, MeanAge, Name, ISBN
You didn't say you wanted ages. If that's the case, don't select it. Also, use the word distinct to take into account books being read by more than one person. In other words, change the code above to this:
SELECT distinct MeanAge, Name, ISBN
You may also want to change this:
SELECT AVG(Age) as MeanAge
to this
SELECT floor(AVG(Age)) as MeanAge
That will cast the MeanAge to an integer and will ensure that if the average age was 15.5, 15 year old people will be excluded from the results.

Where clause that includes IN and NOT IN

SELECT professor.pr_name, professor.pr_college, professor.pr_salary
FROM professor
WHERE professor.pr_salary NOT IN ('Education') > professor.pr_salary IN ('Education')
ORDER BY professor.pr_salary DESC;
I have to make it so that it lists the names of all the professors not in the college of education that earn more than the professors in the college of education. What am I doing wrong?
Since you appear to be asking lots of questions about your assignment, I am not going to present a complete solution - you will need to put that together.
You can find the salaries of the professors in education like this:
SELECT pr_salary
FROM professor
WHERE pr_college = 'Education'
(It is not clear which column the 'Education' value should reference as it is not a salary - you should update this as appropriate - or if it is not in the PROFESSOR table then you ought to update the question with your table definitions.)
You can then use the MAX() aggregation function to find the highest salary of those values.
Similarly, you can find the details of professors not in education like this:
SELECT pr_name,
pr_college,
pr_salary
FROM professor
WHERE pr_college <> 'Education'
ORDER BY pr_salary DESC;
Then you need to add in another filter condition to test if the salaries out of education are higher than the maximum in education using a correlated sub-query:
WHERE ...
AND pr_salary > ( /* Previous maximum value */ )
SELECT professor.pr_name from professor where pr_college<>'Education'and professor.pr_salary >(select max(pr_salary) from professor where pr_college='Education' group by pr_college);

Relational Algebra and Confusing one Complex Examples

We have 3-Relation:
Students(sid, sname)
Courses(cid, cname, dept)
take(sid, cid, grade)
We want to find student numbers of students whose these students take all courses that present in 'CS' department.
why (line 4) is the answer of this query ?
anyone could say differ from (line 1) to (line 3). I read this in Solved-Ex in DB.
Another way to phrase the fourth line is:
all students
except
(
all combinations of students and CS courses
except
all taken courses
)
The set between brackets contains all student + CS course combinations that were not taken. Subtract this from all students, and you get the students that did take all CS exams.

SQL query number of students per school

I have a table of students and schools. How do I select the total students per school?
I'm sure this is a very simple query, however I'm not sure how to proceed on from this:
SELECT tblSchools.name
FROM tblStudentDetails
INNER JOIN tblSchools
ON tblStudentDetails.schoolId = tblSchools.id
Group by the school and use count() to count the students
SELECT s.name, count(d.id) as students_count
FROM tblSchools s
INNER JOIN tblStudentDetails d ON d.schoolId = s.id
GROUP BY s.name
I want to add on to the accepted answer as well. Working for a school district and continuously having to pull counts of students there are a few additional things to keep in mind. What students are you looking for?
Do you want active students, inactive students, or active and inactive students.
Do you want to include students that have been no showed (were going to come to your school, but ended up not coming for even a day, this is recorded in most student information systems.
Is the student attending multiple schools, in which case you want to exclude them from counting in their second or third school.
I've built the script with the idea of a normalized school district database, where things are broken out by school year, and enrollment.
Often a basic script for me looks a little like this.
SELECT s.SCHOOL_NAME, COUNT(stu.STUDENT_GU) AS STUDENT_COUNT
FROM STUDENT stu
JOIN STUDENT_YEAR sy ON sy.STUDENT_ID = stu.STUDENT_ID
JOIN SCHOOL_YEAR scy ON scy.SCHOOL_YEAR_ID = sy.SCHOOL_YEAR_ID
JOIN SCHOOL s ON s.SCHOOL_ID = scy.SCHOOL_ID
JOIN YEAR y ON y.YEAR_ID = sy.YEAR_ID
WHERE y.SCHOOL_YEAR = 2017
AND (sy.CONCURRENT IS NULL OR sy.CONCURRENT OR != 'Not Concurrent')
AND sy.ENTER_DATE IS NOT NULL
AND sy.STATUS IS NULL
GROUP BY s.SCHOOL_NAME
Because each school year is a new year, students, and schools usually have a table for the basic data that doesn't change. But also tables that are school year specific. In my example STUDENT_YEAR and SCHOOL_YEAR is where we get into the specifics regarding which kids we are actually getting, and where they currently are. I utilize the YEAR table to identify which school year I want to look at.
The STUDENT_YEAR table is where we store the students concurrency flag, enter date, and so within that table I can use in the WHERE clause a way to filter out Inactive Students, Concurrent Students, and ensure each student is counted only once.
If those year values aren't included, at least in my database, I would get all students ever enrolled for every year we've got stored.