SQL query number of students per school - sql

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.

Related

How to display a list of departments whose teachers teach DBMS department students?

I have a database in Access. The database has 4 tables:
[DEPARTMENT], [TEACHER], [LECTURE], [SGROUP].
I need to display a list of departments whose teachers teach DBMS department students.
The question is: how to do it? I think it should be a query to join multiple times on the same table ... but I don't understand which table to join ...
I'm a noob.
First, you need to add DepNo value which 3, so the concatenation logically works
INNER JOIN displays everything you want about;
departments whose teachers teach DBMS department students
SELECT DEPARTMENT.DepNo, TEACHER.TechNo, TEACHER.name, DEPARTMENT.name, TEACHER.post
FROM DEPARTMENT
INNER JOIN TEACHER ON DEPARTMENT.DepNo=TEACHER.DepNo
ORDER BY TEACHER.name;
Image chart for What's the INNER JOIN:
Reference:
SQL Joins

sql query to count and display full name

So I am very confused by this query to display teachers' full name. I have used teacher_name ||' '|| teacher_lastname, but when I try to do so for the students, something happens. I am trying to get number of times a teacher had an appointment with a student and display teacher fullname and students full name. Below is my query :
select d.teacher_id ||' '|| d.teacher_lastname as Teacher, count (distinct c.student_id)
from teacher d inner join class t on t.teacher_id=d.teacher_id
inner join classRoom tp on tp.dest_id=t.dest_id
inner join classFl ta on tp.dest_id=ta.dest_id
inner join students c on c.student_id=ta.student_id
group by d.teacher_id,d.teacher_lastname
This is the output, but when I add
select d.teacher_id ||' '|| d.teacher_lastname as Teacher,
c.student_name||' '||c.student_lastname as Student,
count (distinct c.student_id)
and also add it to the group by d.teacher_id,d.teacher_lastname,c.customer_name,c.customer_lastname
it gives the following result
What is wrong? How can I fix it to have the same nr of counts for each teacher?
I am using oracle sql developer
I think you need to remove the DISTINCT from inside the COUNT. You say you want "nr of times a teacher had an appointment with a student" which I interpret to mean that if teacher T saw student S 9 times you want:
T S 9
If you keep DISTINCT, then grouping on student name and counting the number of unique student IDs will only ever produce a 1 unless two students have identical names. In essence then, by keeping the DISTINCT you are counting "the number of different students with name X that that teacher met with" and mostly this is 1 because "1 unique student named Hana Baker met with xxxx yyyy", "1 unique student with name Dream Kenise met with xxxx yyyy" ....
If you do have students with the same name but a different ID, then you should add student ID to the GROUP BY to provide distinction between the two students. You don't have to add it to the SELECT, but you'll struggle to tell them apart if you do. If you have two students both called S, but one has ID 1 (and he saw T 5 times) and the other has ID 2 (and she saw T 4 times) you'll get a result of:
T S 5
T S 4
You might want to add other columns to your select to better tell the difference between them
In your first query, using DISTINCT meant "the number of different students that sought a meeting with the teacher". Omitting DISTINCT in that query would have counted "the number of times the teacher had a meeting with any student"

best performance database design to store students exams result

previously i thought that it's easy to store exams data in simple table like this :
id
subject_id
student_id
mark
date
but i noticed that it is very stupid idea cuz it makes database very huge
let's assume that we have school with 5000 students and there are 12 subjects for each students per month ... it means that our exams table will contain 5000*12*10 = 600000 row per year ,, ok what about if we decided to know student history from joining date to current date
.. i think it's very stupid and i think also there are optimum solutions to make another design to fit my needs ....
i need to store exams data in another lighter way
thank's in advance :)
Here is another way.
Table Student stores name, etc
Table Subject has subject names such as Reading, Writing and Arithmetic, and maybe a MinimumPassingMark.
Table Exam has ExamId, ExamDate, and SubjectID. It may also have PercentageOfOverallGrade
Table StudentExam has StudentID, ExamId, and mark.
Subjects and exams have a one to many relationship (one subject can have many exams, each exam has one subject. Students and exams have a many to many relationship.
So if you want to know if Johnny can read, it's as simple as.
select case
when sum(mark) * PercentageOfOverallGrade >= then 'pass' else 'no' end result
from Student s join StudentExam se on s.StudentId = se.StudentId
join Subject su on se.SubjectId = su.SubjectId
where s.name = 'Johnny'
and su.name = 'Reading'

How can a query return 'yes' if a matching record exists and 'no' if not? SQL / MS Access

I have the following tables:
Student Data
Student ID (primary key)
Prior Education
Student ID (foreign key)
Prior Education Code
At the moment I have a query that displays various data from Student Data with one record per student. I want to add an additional column to this query that shows "Y" if there is at least one matching record in Prior Education and "N" is there is no matching record. Basically I want an answer to the question "Does this student have any prior education?".
I want one record per student in the query regardless of how many records they have in Prior Education.
I'm working in MS Access and have little experience with SQL so solutions that don't require much SQL knowledge are preferable, but not necessary.
You may use LEFT JOIN and IIF.
SELECT student.studentid,iif (isnull(prior.priorid),'Yes','No')
FROM student LEFT JOIN [prior] ON student.studentid = prior.studentid;
EDIT:
SELECT student.studentid, iif(count(prior.priorid)<>0,'Yes','No')
FROM student LEFT JOIN [prior] ON student.studentid=prior.studentid
group by student.studentid

SQL Server query to know if an id in a column equals to other in another column

I’ve been hours trying to build this query and I need your help so I can make it.
This is table Students (made out of inner joins):
SpecialtyChosenID StudentID Subject SubjectSpecialtyID
5ABFB416-8137 15 Math A1EBF3CB-E899
5ABFB416-8137 15 English A1EBF3CB-E899
The info in it means that a student with id no. 15 has chosen an specialty with id 5ABFB416-8137
The two subjects he has passed (Math and English) belong to a specialty with id A1EBF3CB-E899
What would be the query to know if the passed subjects belong to the specialty chosen by the student??
Counting the number of subjects with the same SubjectSpecialtyID as SpecialtyChosenID and vice versa could do.
Thanks a lot
You can do a self join. This finds the number of subjects taken by the student that match the student's chosen specialities.
SELECT l.SpecialtyChosenID, l.StudentID, Count(Distinct r.Subject) FROM Students l
LEFT JOIN Students r ON (l.StudentID=r.StudentID AND l.SpecialityChosenID=r.SubjectSpecialityID)
GROUP BY l.SpecialtyChosenID, l.StudentID
However, this is quite inefficient using the table structure given. If you have a table listing students with their specialities, and another with subjects and specialities, and a third relating students with subjects, it would be better to build this query from the base data, rather than from the derived data.
SELECT * FROM Students WHERE SpecialtyChosenID = SubjectSpecialtyID
If you only need the list of matching subjects and you have the SpecialtyChosenID you can do something like
SELECT * FROM Students
WHERE SubjectSpecialtyID = SpecialityChosenID
CASE WHEN SpecialtyChosenID = SubjectSpecialtyID THEN 1 ELSE 0 END AS specialty