Oracle SQL, not exist and count - sql

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

Related

If I have multiple values in a column, how can I count it in 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;

How do I select mothers in the table that have children of all the listed genders? (implementing RA Division in SQL)

I have a table (person) with the following columns:
name, gender, mother
and I need to extract the names of the mothers who have a baby of every gender. I'm not allowed to assume that gender is limited to just M and F.
I can do SELECT DISTINCT person.gender FROM person to get a list of all genders present in the table.
I also created a table with all the names of the mothers and their child's gender as the two columns.
The problem is, I have no idea how to check if a mother has had a child of all respective genders in the table. How can I implement this?
Edit: How I achieved my final solution can be found below, thank you all for your answers! I have also updated the title to help others find it.
Group the mothers' records together, and in each group count how many distinct genders there are.
SELECT
mother
FROM
person
GROUP BY
mother
HAVING
COUNT(DISTINCT gender) = (SELECT COUNT(DISTINCT gender) FROM person)
I ultimately approached the issue the same as #MatBailie but found it useful to include the COUNT in the final query as well. You basically need two things to make this type of query work. 1) A collection of distinct mothers, 2) The number of distinct genders. A GROUP BY and an aggregate subquery works nicely here.
SELECT COUNT(DISTINCT gender) AS genderCount, mother FROM person
GROUP BY mother
HAVING genderCount = (SELECT COUNT(DISTINCT gender) from person);
In the end I implemented the relational algebra division method into SQL using various EXCEPT and IN conditions. Relational algebra division works great when you have two columns, where some kind of label (e.g. a name) is connected to some type (e.g. gender), and you wish to find if a specific label is linked to all types that are specified in another, separate table.
In my case the list of labels were the names of the mothers, and their associated type was the gender of their child. Using the SELECT statement I created in my question post, this gave me a list of genders where each mother must have for my query. This was my "type" table, that all the mothers had to link to.
This is how I got the answer to my question in the end.
A nice, detailed guide on how to implement it is here:
https://www.geeksforgeeks.org/sql-division/
The other answers do also work and are much simpler, but this solution feels more general and I think it should be shared!

Incorrect Command (INSERT INTO ... SELECT with GROUP BY)

The exercise for my online course is as follows
This time, the university needs a list of average results of written and oral exams in each subject (from the exam table).
The new table, report_average_scores consists of the following columns: subject, avg_written_exam_score, and avg_oral_exam_score (which are of type DECIMAL(4,2)).
Help the university insert data into the report_average_scores table.
I have attempted adding the GROUP BY as I should, but I am unable to pass the section. Also, I can not find where the decimal would play part.
INSERT INTO report_average_scores
(
subject,
avg_written_exam_score,
avg_oral_exam_score
)
SELECT
subject,
written_exam_score,
oral_exam_score
FROM exam;
I expect the output to approve the code, but I am running into the same error.
Am I seeing it wrong or you just need to average?
SELECT
subject,
AVG(written_exam_score),
AVG(oral_exam_score)
FROM exam group by subject

List faculty members who have smaller or equal salary than their supervisor by using SELF(RECURSIVE) JOIN

Below is the table Faculty
This is the query question from my assignment which is shown below:
List faculty members who have a smaller or equal salary than their supervisor. List the Social Security number, last name and salary of the faculty and supervisor.
(Hint: use a recursive join)
This is how I approached which is shown below:
SELECT Faculty.FacSSN, Faculty.FacLastName, Faculty.FacSalary, Faculty.FacSupervisor, S.FacLastName, S.FacSalary
FROM Faculty, Faculty S
WHERE NOT Faculty.FacSSN = Faculty.FacSupervisor
AND Faculty.FacSalary <= S.FacSalary
AND NOT Faculty.FacLastName = S.FacLastName
AND Faculty.FacSupervisor IS NOT NULL;
This is the following result I'm getting which is shown below
I'm getting the result of Supervisor's salary greater than or equal to Faculty member's salary. But the problem is I'm also getting result of Faculty member's salary (who are not supervisors) being greater than or equal to other Faculty member's salary.
How do I solve this problem ?
Can someone correct my SQL code ?
Access does not support recursive joins, you will have to switch the DBMS for that. Also see Is it possible to create a recursive query in Access?
That said, this problem doesn't seem to need recursive joins, because only the direct supervisor is needed, not the whole hierarchy to the top.
Looking at your query I'm not sure what you were going for using WHERE NOT Faculty.FacSSN = Faculty.FacSupervisor (There is no one being their own supervisor), but if you change that to WHERE S.FacSSN = Faculty.FacSupervisor it should work.
A cleaned up version would look like this:
SELECT F.FacSSN, F.FacLastName, F.FacSalary, F.FacSupervisor, S.FacLastName, S.FacSalary
FROM Faculty AS F
INNER JOIN Faculty AS S ON S.FacSSN = F.FacSupervisor
WHERE F.FacSalary <= S.FacSalary

Priority in SQL queries

Three tables:
Employees {EmployeeID, EmployeeName}
Courses {CourseID, CourseName}
TrainingLog {LogID, EmployeeID, CourseID)
There's one position left in a course and the priority is to give it to someone who's never done a course before, then someone who has done courses but not this one, then anyone. The course must be filled.
Can the appropriate employee be found in one query?
Ya. It can be done.
Join Employees with TrainingLog on the courseId in question.
Some number of employees will not match yielding a NULL courseid.
order the set by DESC with NULLs first in the list.
rank them by rownum, and pick the first row.
if there is no first row, then there is noone to assign to the class.
otherwise,
if the first one in the list will be the person to assign.
base on the problem you want to resolve this could not be possible if you'll try to do it on query alone you have to work the logic with your application as well perhaps you'd love to create a stored procedure for this kind of conditions.