SQL Query to check if a record does not exist in another table - sql

I have a table which holds details of all Students currently enrolled in classes which looks like this:
CREATE TABLE studentInClass(
studentID int,
classID int,
FOREIGN KEY(studentID) references students(studentID),
foreign key(classID) references class(classID)
);
And another table which contains details of students who have paid for classes:
CREATE TABLE fees(
feesID INTEGER PRIMARY KEY AUTOINCREMENT,
StudentID INTEGER,
AmountPaid INT,
Date DATE,
FOREIGN KEY(StudentID) REFERENCES students(StudentID));
What I want to do is check whether a student who is in a class has not paid for that class. I am struggling to write a SQL query which does so. I have tried multiple queries such as:
Select studentInClass.StudentID
from fees, studentInClass
where fees.StudentID = studentInClass.StudentID;
But this returns no data. I'm not sure how to proceed from here. Any help will be appreciated.

You want outer join :
select s.StudentID, (case when f.AmountPaid is not null
then 'Yes'
else 'No'
end) as Is_fees_paid
from studentInClass s left join
fees f
on f.StudentID = s.StudentID;

With NOT EXISTS:
select s.*
from studentInClass s
where not exists (
select 1 from fees
where studentid = s.studentid
)
with this you get all the rows from the table studentInClass for which there is not the studentid in the table fees.
It's not clear if you also need to check the date.

check it please:
select studentInClass.StudentID
from studentInClass inner join fees ON fees.StudentID = studentInClass.StudentID

Related

SQL Find all courses who have more students enrolled then the allowed enroll_limit for the course

I'm currently taking a database class and I am stuck on a homework problem due tonight
Find the courses given in the ‘Sloan’ building which have enrolled more students than their enrollment limit. Return the courseno, enroll_limit, and the actual enrollment for those courses.
I'm stuck trying to count how many students are in each course.
CREATE TABLE Course (
courseno VARCHAR(7),
credits INTEGER NOT NULL,
enroll_limit INTEGER,
classroom VARCHAR(10),
PRIMARY KEY(courseNo), );
CREATE TABLE Student (
sID CHAR(8),
sName VARCHAR(30),
major VARCHAR(10),
trackcode VARCHAR(10),
PRIMARY KEY(sID),
FOREIGN KEY (major,trackcode) REFERENCES Tracks(major,trackcode) );
CREATE TABLE Enroll (
courseno VARCHAR(7),
sID CHAR(8),
grade FLOAT NOT NULL,
PRIMARY KEY (courseNo, sID),
FOREIGN KEY (courseNo) REFERENCES Course(courseNo),
FOREIGN KEY (sID) REFERENCES Student(sID) );
My current very broken attempt is
SELECT sloancourse.courseno
FROM course sloancourse
WHERE
sloancourse.classroom = 'Sloan'
and sloancourse.courseno IN (
SELECT c.courseno
FROM student s, enroll e, course c
WHERE
c.courseno = e.courseno
and s.sid = e.sid
and sloancourse.courseno = c.courseno
)
;
Find the courses given in the ‘Sloan’ building which have enrolled more students than their enrollment limit. Return the courseno, enroll_limit, and the actual enrollment for those courses.
You would typically join courses and enrollment (using stanard join syntax, with the on keyword), group by course, and finally filter on courses whose student count with a having clause.
select
c.courseno,
c.enroll_limit,
count(*) actual_enrollment
from course c
inner join enroll e on e.courseno= c.courseno
where c.classroom = 'Sloan'
group by c.courseno, c.enroll_limit
having count(*) > c.enroll_limit
Note that you don't need to bring in the student table to get the desired results.
You could try something like this:
SELECT
Course.courseno,
Course.enroll_limit,
Couse.classroom
FROM Course, Enroll
WHERE Course.courseno = Enroll.courseno
AND Course.classroom = 'Sloan'
GROUP BY Course.courseno
HAVING count(*) > Course.enroll_limit
Postgres docs have an example on these aggregate functions: https://www.postgresql.org/docs/current/tutorial-agg.html
Basically, when you group by one or multiple properties, the resulting table will result in a unique row for the property/combination of properties. In this example, you would have one row for each of the courseno unique values (as they are grouped by this value).

Is there a way to select this name from more than one table?

I need to select the item name and the vendor name for each item that belongs to the vendor with a rating bigger than 4. And I can't find a way, I know it's something with joins but the 2 of them have the same column name.
CREATE TABLE venedors(
id int PRIMARY KEY,
name varchar2(20),
rating int)
CREATE TABLE items(
id int PRIMARY KEY,
name varchar2(20),
venedorId int references venedors(id))
If i understanded your problem.
Select items.name as itemName, venedors.name as vendorName
from items
inner join venedors
on items.venedorId = venedors.id
where venedors.rating > 4
If you want get all the vendors irrespective whether there are items associated with vendors or not, then try with left join as shown below:
Select v.name as vendorName, i.name as itemName
from venedors v
left join items i
on i.venedorId = v.id
where v.rating > 4

Appropriate SELECT Statement

I have the following tables:
CREATE TABLE Subject
(
Subject_Code INTEGER,
Subject_Year VARCHAR (8),
PRIMARY KEY (Subject_Code, Subject_Year),
Teacher_ID INTEGER REFERENCES
);
CREATE TABLE Teacher
(
TeacherID INTEGER PRIMARY KEY,
FirstName TEXT,
Department_ID INTEGER References Academic Department(Department_ID)
);
CREATE TABLE Subject-taken
(
Marks_Obtained INTEGER,
Subject_Code INTEGER REFERENCES subject (Subject_Code),
Candidate_ID INTEGER REFERENCES Candidate (Candidate_ID),
PRIMARY KEY (Subject_Code, Candidate_ID)
);
CREATE TABLE Academic_Department
(
Department_ID INTEGER PRIMARY KEY,
Department_Name TEXT
);
I've already tried the following select statement
SELECT m.subject_code,
MIN (marks_obtained) AS Min_Marks,
MAX (marks_obtained) AS Max_Marks
FROM Subject-taken m, Subject a
GROUP BY m.Subject_Code;
Want to use the join function any suggestions on where to use it in order to join the departments with subjects and students
Make use of joins to link your data between tables. Use group by to make statistics by some fields. You can try something like this:
SELECT
Subjects.Subject_Code,
Subjects.Subject_Name,
Teachers.TeacherID,
Academic_Department.Department_ID,
min(Subject-taken.Marks_Obtained) as min_marks,
max(Subject-taken.Marks_Obtained) as max_marks,
avg(Subject-taken.Marks_Obtained) as avg_marks,
stddev_samp(subject-taken.Marks_Obtained) as stddev_marks
FROM
Subjects LEFT JOIN
Teachers ON Subjects.TeacherID = Subjects.TeacherID LEFT JOIN
Academic_Department ON Teachers.Department_ID = Academic_Department.Department_ID LEFT JOIN
Subject-taken ON Subjects.Subject_Code = Subject-taken.Subject_Code
GROUP BY
Subjects.Subject_Code,
Subject.Subject_Name,
Teacher.TeacherID,
Academic_Department.Department_ID
I don't really know if stddev_samp is the aggregate function you need, stddev_pop is also available. Please refer to this PostgreSQL documentation table to find out.

Oracle APEX Join and Count

I have two tables created with SQL code:
CREATE TABLE
TicketSales(
purchase# Number(10),
client# Integer CONSTRAINT fk1 REFERENCES Customers,
PRIMARY KEY(purchase#));
CREATE TABLE Customers(
client# Integer,
name Char(30),
Primary Key(client#);
Basically table TicketSales holds ticket sales data and client# is foreign key referenced in customers table. I would like to count names that are in TicketSales table. i tried below code with no success:
select Count(name)
From Customers
Where Customers.Client#=TicketSales.Client#
Group by Name;
Any help appreciated.
Thanks,
If you want a count by each name, then include name in the select and group by clauses
select c.Name, Count(*)
From Customers c
INNER JOIN TicketSales t ON c.Client# =t.Client#
Group by c.Name;
If you want just the count of names, not tickets, then use
select Count(*)
From Customers c
;
Or, for a count of individuals who have tickets recrded against them:
select Count(DISTINCT t.Client#)
From TicketSales t
;

Output student number that exists only on primary key but doesn't exist on foreign key

I have two tables
Student table
student number primary key
Grade table
student number foreign key
I want to display only students that exist in the student table but don't exist in the grade table
This way you can select all students that are not found (by their id) in the grade table.
SELECT *
FROM student
WHERE id NOT IN (SELECT student_id FROM grade)
Just to round out the answers I usually prefer using joins for things like this a simple left join and testing for null value will do the trick.
SELECT s.*
FROM
student s
LEFT JOIN grade g
WHERE
g.student_Id IS NULL