If I have multiple values in a column, how can I count it in SQL? - sql

Let me illustrate this:
Student_ID
Course
StudentID1
CourseA
StudentID2
CourseB
StudentID3
CourseA CourseB
There is an existing table that has data that looks like the one above (Not exactly Student & Course, this is more for illustration purpose) and my job is to do a count of how many students for each course. The table is very huge and I do not know how many and what are the courses are out there (Easily in thousands), so wonder if there is a way I can get a list of all these courses and their counts through SQL?
The current method that my team did is SELECT DISTINCT COURSE, COUNT(STUDENT_ID) FROM TABLE GROUP BY COURSE, but this does not work because it treats "CourseA CourseB" as its own.
There are some other columns in this table that I might need to do a SUM as well.
Appreciate any advice on this, thanks!

you could use below to find number of students for each course:
select course, count(*) as no_of_students
from table
group by course;

Related

Can I skip a join in my select?

When learing about joins, our instructor says to not skip tables.
For example, lets do a query that Selects the Last_Name, First_name, and Numeric_Grade.
I would write
Select Last_Name, First_Name, Numeric_Grade
From Student
Join Grade
Using(Student_id)
He says to write
Select Last_Name, First_Name, Numeric_Grade
From Student
Join Enrollment
Using(Student_id)
Join Grade
Using(Student_id)
Im confused because as long as long as i can link them through similar fields, i dont see the point of going enrollment.
He has not given me a reason for going through enrollment, other than its what the Diagram shows. Follow the diagram.
Do I have to go through Enrollment? Is it the safe way to do it, or does it not matter because Grade and Student have a Student_id primary key?
Quoting Alice Rischert in Oracle SQL By Example, lab 7.2:
The second choice is to join the STUDENT_ID from the GRADE table directly to the STUDENT_ID of the STUDENT table, thus skipping the ENROLLMENT table entirely. - - This shortcut is perfectly acceptable, even if it does not follow the primary key/foreign key relationship path. In this case, you can be sure not to build a Cartesian product because you can guarantee only one STUDENT_ID in the STUDENT table for every STUDENT_ID in the GRADE table. In addition, it also eliminates a join; thus, the query executes a little faster and requires fewer resources. The effect is probably fairly negligible with this small result set.
The only reason to go through the Enrollment table would be if you need information (fields) from that table. If both the Enrollment and Grade table have a Student_id field then you wouldn't need to go through Enrollment to get there.
In your example it looks like you are looking for First and Last Name, which should both come from the Student table and Numeric_Grade which should come from the Grade table. In this instance, there would be no need for the Enrollment table. If there were a WHERE clause that required something from the Enrollment table then yes you would need to include it, but your example I would say it is not needed.
If this is a question on a test or assignment and the teacher is requesting you go through the Enrollment table too I would do it just to appease him, but knowing that you don't actually need to do it to get the information that you require.
Depend on your tables. Sometimes you can but sometimes dont.
For example imagine in enrollment you have something like student_quit_course
Then you may only want grade of student actually finish the course and you need all three table
For this particular case you will have a GRADE for several section_id but to know what is that section you need [Section] and [Course] both join using [Enrollment]

SQL - count with or without subquery?

I have two tables in my DB:
Building(bno,address,bname) - PK is bno. bno
Room(bno,rno,floor,maxstud) - PK is bno,rno (together)
The Building table stands for a building number, address and name.
The Room table stands for building number, room number, floor number and maximum amount of students who can live in the room.
The query I have to write:
Find a building who has at least 10 rooms, which the maximum amount of students who can live in is 1. The columns should be bno, bname, number of such rooms.
What I wrote:
select building.bno, building.bname, count(rno)
from room natural join building
where maxstud =1
group by bno, bname
having count(rno)>=10
What the solution I have states:
with temp as (
select bno, count(distinct rno) as sumrooms
from room
where maxstud=1
group by bno
)
select bno, bname, sumrooms
from building natural join temp
where sumrooms>=10
Is my solution correct? I didn't see a reason to use a sub-query, but now I'm afraid I was wrong.
Thanks,
Alan
Your query will perform faster but I'm afraid won't compile because you are not including every unaggregated column in the GROUP BY clause (here: building.bname).
Also, the solution that you have which isn't yours counts distinct room numbers, so one may conclude that a building can have several rooms with the same numbers for example on different floors, so that a room would be identified correctly by the unique triple (bno, rno, floor).
Given what I've wrote above your query would look:
select building.bno, building.bname, count(distinct rno)
from room natural join building
where maxstud = 1
group by 1,2 -- I used positions here, you can use names if you wish
having count(distinct rno) >= 10
Your solution is better.
If you are unsure, run both queries on a sample dataset and convince yourself that the results are the same.

Access flag record when match found in table 2 (one-to-many relationship)

I have an educational db with a tbl_Students and tblStudentPrograms. The tblStudentPrograms has one record per student and program (ProgramID) per year (YearID.
I need to find out how many students participated in ProgramID=2 EVER. So, I need the DISTINCT subset of students who have participated in the program for any YearID.
(Of course, this will be complicated further by trying to find other records in other tables such as StudentAdvising as well , but this will be a good start.)
Thank you!
SELECT DISTINCT count(studentID) FROM tblStudentPrograms WHERE ProgramID = 2
Assuming you want a distinct count of students (excluding those where the same student may have taken a program twice...
SELECT count(distinct StudentID)
FROM tblStudentPRograms
WHERE ProgramID = 2
Assuming you want a distinct count of students (excluding those where the same student may have taken a program twice...
SELECT count(distinct StudentID)
FROM tblStudentPRograms
WHERE ProgramID = 2
though I'm not positive access supports a distinct w/in a count like other RDBMS do...
so you may have to do:
SQL : how can i count distinct record in MS ACCESS
SELECT count(BStudentID) as DistinctStudentsInProgram
FROM (select distinct studentID, ProgramID from tblStudentPrograms) B
WHERE B.ProgramID = 2

Oracle SQL, not exist and count

I am currently stuck with my assignment. I am not trying to be lazy but I can't seems to find a solution and my teacher guided me by saying to use not exist or count.
I need to find patients name who have been treated by all the doctors. Currently I am just using plain intersect SQL command for each doctor name (In the question, there are only 3 doctors) but of course its not realistic when there are 100's of doctors name.
The scheme is as below.
Patient (PatientID, FamilyName, GivenName)
Account (ProviderNo, PatientID)
Doctor (ProviderNo, Name)
Any help would be greatly appreciated.
I won't provide you the exact Query.
But here is the psuedo code:
group PatientId in Account where its distinct ProviderNo count should be
equal to no. of Doctors

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