SQL - Combined Content
Joins in SQL (Student Database)
SQL uses joins to retrieve data from multiple tables based on logical relationships between
them.
Joins enable you to combine data from two or more tables into a single result set.
✓ INNER JOIN
Types of SQL Joins:
✓ OUTER JOINs (LEFT, RIGHT, FULL)
✓ EQUI JOIN
✓ NON-EQUI JOIN
✓ NATURAL JOIN
✓ SELF JOIN
✓ CROSS JOIN
------------------------------------------------------------
Schema for Student Database
Course Table
CREATE TABLE Course (
CourseID NUMBER(5) PRIMARY KEY,
CourseName VARCHAR2(30) NOT NULL,
Location VARCHAR2(20)
);
Student Table
CREATE TABLE Student (
StudentID NUMBER(5) PRIMARY KEY,
StudentName VARCHAR2(30) NOT NULL,
CourseID NUMBER(5),
AdvisorID NUMBER(5),
EnrollDate DATE,
Marks NUMBER(5),
CONSTRAINT fk_course FOREIGN KEY (CourseID) REFERENCES Course(CourseID)
);
Enrollment Table
CREATE TABLE Enrollment (
EnrollID NUMBER(5) PRIMARY KEY,
StudentID NUMBER(5),
CourseID NUMBER(5),
CONSTRAINT fk_enroll_course FOREIGN KEY (CourseID) REFERENCES Course(CourseID),
CONSTRAINT fk_enroll_student FOREIGN KEY (StudentID) REFERENCES
Student(StudentID)
);
GradeScale Table (for Non-Equi Join)
CREATE TABLE GradeScale (
Grade CHAR(1) PRIMARY KEY,
MinMarks NUMBER(5),
MaxMarks NUMBER(5)
);
-- Insert Sample Data
INSERT INTO Course VALUES (101, 'Mathematics', 'Chennai');
INSERT INTO Course VALUES (102, 'Computer Science', 'Bangalore');
INSERT INTO Course VALUES (103, 'Physics', 'Hyderabad');
INSERT INTO Student VALUES (1, 'Arun', 101, NULL, '10-JAN-20', 78);
INSERT INTO Student VALUES (2, 'Bhavya', 102, 1, '15-FEB-21', 85);
INSERT INTO Student VALUES (3, 'Charan', 102, 1, '01-JUN-19', 92);
INSERT INTO Student VALUES (4, 'Divya', 103, 3, '21-AUG-22', 60);
INSERT INTO Student VALUES (5, 'Eshan', NULL, NULL, '12-JAN-23', 74);
INSERT INTO Enrollment VALUES (201, 1, 101);
INSERT INTO Enrollment VALUES (202, 2, 102);
INSERT INTO Enrollment VALUES (203, 3, 102);
INSERT INTO GradeScale VALUES ('A', 90, 100);
INSERT INTO GradeScale VALUES ('B', 75, 89);
INSERT INTO GradeScale VALUES ('C', 60, 74);
------------------------------------------------------------
Demonstrating Joins
(a) INNER JOIN / EQUI JOIN
SELECT [Link], [Link], [Link]
FROM Student s
INNER JOIN Course c
ON [Link] = [Link];
-- Returns only students with matching courses.
(b) LEFT OUTER JOIN
SELECT [Link], [Link]
FROM Student s
LEFT OUTER JOIN Course c
ON [Link] = [Link];
-- Shows all students even if they don’t belong to any course (Eshan will appear with NULL
CourseName).
(c) RIGHT OUTER JOIN
SELECT [Link], [Link]
FROM Student s
RIGHT OUTER JOIN Course c
ON [Link] = [Link];
-- Shows all courses, even if no student enrolled.
(d) FULL OUTER JOIN
SELECT [Link], [Link]
FROM Student s
FULL OUTER JOIN Course c
ON [Link] = [Link];
-- Shows all students + all courses.
(e) NON-EQUI JOIN (using GradeScale)
SELECT [Link], [Link], [Link]
FROM Student s, GradeScale g
WHERE [Link] BETWEEN [Link] AND [Link];
-- Classifies each student into Grade A, B, or C.
(f) NATURAL JOIN
SELECT StudentID, StudentName, CourseName
FROM Student NATURAL JOIN Course;
-- Works because both have CourseID column.
(g) SELF JOIN (Advisor-Student Relationship)
SELECT [Link] AS Student, [Link] AS Advisor
FROM Student s
LEFT JOIN Student a
ON [Link] = [Link];
-- Displays student–advisor hierarchy.
(h) CROSS JOIN
SELECT [Link], [Link]
FROM Student s
CROSS JOIN Course c;
-- Produces Cartesian product (every student with every course).
------------------------------------------------------------
Practice Queries
SELECT [Link], [Link], [Link]
FROM Student s
INNER JOIN Course c
ON [Link] = [Link];
SELECT [Link], [Link]
FROM Enrollment e
INNER JOIN Course c
ON [Link] = [Link];
SELECT [Link], [Link]
FROM Student s
LEFT JOIN Course c
ON [Link] = [Link];
SELECT [Link], [Link]
FROM Enrollment e
RIGHT JOIN Course c
ON [Link] = [Link];
SELECT [Link], [Link]
FROM Student s
RIGHT JOIN Course c
ON [Link] = [Link];
SELECT [Link], [Link]
FROM Student s
FULL OUTER JOIN Course c
ON [Link] = [Link];
SELECT [Link], [Link], [Link]
FROM Student s, GradeScale g
WHERE [Link] BETWEEN [Link] AND [Link];
SELECT [Link] AS Student, [Link] AS Advisor
FROM Student s
LEFT JOIN Student a
ON [Link] = [Link];
SELECT [Link], [Link]
FROM Student s
CROSS JOIN Course c;
Views in SQL (Student Database)
1. Simple Views
2. Views with Joins
3. Views with Aggregates
4. Complex Views (Subqueries, Non-Equi Joins)
5. Read-only Views
6. Updatable Views
7. Views for Security
Course Table
CREATE TABLE Course (
CourseID NUMBER(5) PRIMARY KEY,
CourseName VARCHAR2(30) NOT NULL,
Location VARCHAR2(20)
);
Student Table
CREATE TABLE Student (
StudentID NUMBER(5) PRIMARY KEY,
StudentName VARCHAR2(30) NOT NULL,
CourseID NUMBER(5),
AdvisorID NUMBER(5),
EnrollDate DATE,
Marks NUMBER(5),
CONSTRAINT fk_course FOREIGN KEY (CourseID) REFERENCES Course(CourseID)
);
Enrollment Table
CREATE TABLE Enrollment (
EnrollID NUMBER(5) PRIMARY KEY,
StudentID NUMBER(5),
CourseID NUMBER(5),
CONSTRAINT fk_enroll_course FOREIGN KEY (CourseID) REFERENCES Course(CourseID),
CONSTRAINT fk_enroll_student FOREIGN KEY (StudentID) REFERENCES
Student(StudentID)
);
GradeScale Table
CREATE TABLE GradeScale (
Grade CHAR(1) PRIMARY KEY,
MinMarks NUMBER(5),
MaxMarks NUMBER(5)
);
-- Insert Sample Data
INSERT INTO Course VALUES (101, 'Mathematics', 'Chennai');
INSERT INTO Course VALUES (102, 'Computer Science', 'Bangalore');
INSERT INTO Course VALUES (103, 'Physics', 'Hyderabad');
INSERT INTO Student VALUES (1, 'Arun', 101, NULL, TO_DATE('10-JAN-2020','DD-MON-
YYYY'),
78);
INSERT INTO Student VALUES (2, 'Bhavya', 102, 1, TO_DATE('15-FEB-2021','DD-MON-
YYYY'),
85);
INSERT INTO Student VALUES (3, 'Charan', 102, 1, TO_DATE('01-JUN-2019','DD-MON-
YYYY'),
92);
INSERT INTO Student VALUES (4, 'Divya', 103, 3, TO_DATE('21-AUG-2022','DD-MON-
YYYY'),
60);
INSERT INTO Student VALUES (5, 'Eshan', NULL, NULL,
TO_DATE('12-JAN-2023','DD-MON-YYYY'), 74);
INSERT INTO Enrollment VALUES (201, 1, 101);
INSERT INTO Enrollment VALUES (202, 2, 102);
INSERT INTO Enrollment VALUES (203, 3, 102);
INSERT INTO GradeScale VALUES ('A', 90, 100);
INSERT INTO GradeScale VALUES ('B', 75, 89);
INSERT INTO GradeScale VALUES ('C', 60, 74);
-----------------------------------------------------------
1. Simple View — View All Students
CREATE VIEW v_all_students AS
SELECT StudentID, StudentName, Marks
FROM Student;
2. View with Join — Student & Course
CREATE VIEW v_student_course AS
SELECT [Link], [Link], [Link], [Link], [Link]
FROM Student s
JOIN Course c ON [Link] = [Link];
3. View with Aggregation — Course-wise Average Marks
CREATE VIEW v_avg_marks_course AS
SELECT [Link], ROUND(AVG([Link]), 2) AS AvgMarks
FROM Student s
JOIN Course c ON [Link] = [Link]
GROUP BY [Link];
4. Complex View — Students with Grade (Non-Equi Join)
CREATE VIEW v_student_with_grade AS
SELECT [Link], [Link], [Link], [Link]
FROM Student s
JOIN GradeScale g
ON [Link] BETWEEN [Link] AND [Link];
5. Read-Only View — Only Advisors
CREATE VIEW v_advisors AS
SELECT StudentID, StudentName
FROM Student
WHERE StudentID IN (SELECT DISTINCT AdvisorID FROM Student WHERE AdvisorID IS
NOT
NULL)
WITH READ ONLY;
6. Updatable View — Basic Student Details
CREATE VIEW v_basic_student AS
SELECT StudentID, StudentName, Marks
FROM Student;
-- Example Update:
UPDATE v_basic_student SET Marks = Marks + 5 WHERE StudentID = 4;
7. Security View — Mask Marks (Show only for Mathematics)
CREATE VIEW v_masked_marks AS
SELECT StudentID, StudentName,
CASE
WHEN CourseID = 101 THEN Marks
ELSE NULL
END AS Marks
FROM Student;
8. Subquery View — Top Scorer in Each Course
CREATE VIEW v_top_scorers AS
SELECT *
FROM (
SELECT [Link], [Link], [Link], [Link],
RANK() OVER (PARTITION BY [Link] ORDER BY [Link] DESC) AS rk
FROM Student s
)
WHERE rk = 1;
9. View with NULL Handling — Students without Courses
CREATE VIEW v_student_no_course AS
SELECT StudentID, StudentName, Marks
FROM Student
WHERE CourseID IS NULL;
10. Join Multiple Tables — Enrollment with Course & Students
CREATE VIEW v_enrollment_info AS
SELECT [Link], [Link], [Link]
FROM Enrollment e
JOIN Course c ON [Link] = [Link]
JOIN Student s ON [Link] = [Link];
Sub Queries in SQL (Student Database)
Subquery Types
Type Description
- Simple Subquery: One value returned (Scalar)
- Multi-row Subquery: Returns multiple rows
- Subquery in FROM clause: Acts like a temporary table
- Correlated Subquery: Depends on outer query
- Subquery in WHERE/SELECT/HAVING: Filtering, conditions
- EXISTS / NOT EXISTS: Check if data exists
- Nested Subqueries: Subqueries within subqueries
1. Simple Scalar Subquery — Find Student with Highest Marks
SELECT StudentID, StudentName, Marks
FROM Student
WHERE Marks = (SELECT MAX(Marks) FROM Student);
2. Multi-Row Subquery with IN — Students Enrolled in CS or Math
SELECT StudentName, CourseID
FROM Student
WHERE CourseID IN (
SELECT CourseID FROM Course WHERE CourseName IN ('CS', 'Math')
);
3. Subquery in FROM Clause (Inline View) — Average Marks by Course
SELECT CourseName, AvgMarks
FROM (
SELECT [Link], ROUND(AVG([Link]), 2) AS AvgMarks
FROM Student s
JOIN Course c ON [Link] = [Link]
GROUP BY [Link]
);
4. Correlated Subquery — Students Scoring Above Course Average
SELECT StudentID, StudentName, CourseID, Marks
FROM Student s
WHERE Marks > (
SELECT AVG(Marks)
FROM Student
WHERE CourseID = [Link]
);
5. Subquery with EXISTS — Courses with Students
SELECT CourseID, CourseName
FROM Course c
WHERE EXISTS (
SELECT 1
FROM Student s
WHERE [Link] = [Link]
);
6. Subquery in SELECT Clause — Student with Their Grade
SELECT
StudentID,
StudentName,
Marks,
(SELECT Grade
FROM GradeScale g
WHERE [Link] BETWEEN [Link] AND [Link]) AS Grade
FROM Student s;
7. Nested Subquery — Students in Same Course as 'Amit'
SELECT StudentName, CourseID
FROM Student
WHERE CourseID = (
SELECT CourseID
FROM Student
WHERE StudentName = 'Amit'
);
8. Subquery with NOT IN — Students Not Assigned to Any Course
SELECT StudentID, StudentName
FROM Student
WHERE CourseID NOT IN (
SELECT CourseID FROM Course
);
9. Top 1 Marks in Each Course (Correlated + RANK)
SELECT *
FROM (
SELECT
StudentID,
StudentName,
CourseID,
Marks,
RANK() OVER (PARTITION BY CourseID ORDER BY Marks DESC) AS rk
FROM Student
)
WHERE rk = 1;
10. Subquery with Aggregation in HAVING Clause — Courses with Avg Marks > 75
SELECT [Link], AVG([Link]) AS AvgMarks
FROM Student s
JOIN Course c ON [Link] = [Link]
GROUP BY [Link]
HAVING AVG([Link]) > 75;
Practice Exercises Using Subqueries
SELECT StudentID, StudentName, Marks
FROM Student
WHERE Marks > (SELECT AVG(Marks) FROM Student);
SELECT CourseName
FROM Course c
WHERE EXISTS (
SELECT 1 FROM Student s
WHERE [Link] = [Link] AND [Link] > 90
);
SELECT StudentID, StudentName
FROM Student
WHERE CourseID NOT IN (SELECT CourseID FROM Enrollment WHERE CourseID IS NOT
NULL);
SELECT StudentID, StudentName
FROM Student s
WHERE AdvisorID IS NOT NULL
AND (SELECT Marks FROM Student a WHERE [Link] = [Link]) > 95;
SELECT StudentID, StudentName, CourseID
FROM Student
WHERE CourseID = (
SELECT CourseID
FROM (
SELECT CourseID, AVG(Marks) AS AvgMarks
FROM Student
GROUP BY CourseID
ORDER BY AvgMarks
)
WHERE ROWNUM = 1
);
Practice Questions — SQL Views
CREATE VIEW v_student_marks AS
SELECT StudentName, Marks
FROM Student;
CREATE VIEW v_student_course_location AS
SELECT [Link], [Link], [Link]
FROM Student s
JOIN Course c ON [Link] = [Link];
CREATE VIEW v_student_grade AS
SELECT [Link], [Link], [Link], [Link]
FROM Student s
JOIN GradeScale g
ON [Link] BETWEEN [Link] AND [Link];
CREATE VIEW v_high_scorers AS
SELECT StudentID, StudentName, Marks
FROM Student
WHERE Marks > 75;
CREATE VIEW v_course_avg_marks AS
SELECT [Link], ROUND(AVG([Link]), 2) AS AvgMarks
FROM Student s
JOIN Course c ON [Link] = [Link]
GROUP BY [Link];
CREATE VIEW v_enrollment_course AS
SELECT [Link], [Link], [Link]
FROM Enrollment e
JOIN Student s ON [Link] = [Link]
JOIN Course c ON [Link] = [Link];
CREATE VIEW v_student_advisor AS
SELECT [Link], [Link] AS AdvisorName
FROM Student s
LEFT JOIN Student a ON [Link] = [Link];
CREATE VIEW v_student_no_course AS
SELECT StudentID, StudentName
FROM Student
WHERE CourseID IS NULL;
CREATE VIEW v_courses AS
SELECT CourseName, Location
FROM Course
WITH READ ONLY;
CREATE VIEW v_top_scorers AS
SELECT *
FROM (
SELECT StudentID, StudentName, CourseID, Marks,
RANK() OVER (PARTITION BY CourseID ORDER BY Marks DESC) AS rk
FROM Student
)
WHERE rk = 1;
Challenge Questions:
1) Create a view to show how many students are there in each course.
2) Create a view to mask marks for all courses except Math (only Math shows real marks).
3) Create a view to show only the latest enrolled student from each course.
4) Create a view to display all courses and whether they currently have enrollments.
5) Create an updatable view that allows changes to student marks and name, but not their
course
or advisor.
6) List students who scored more than the average marks in their course, excluding courses
with
fewer than 2 students.
7) Find courses where all students are enrolled only within their course domain.
8) For each course, show the difference between the highest and lowest marks.
9) List students who enrolled before the average enrollment date and scored below the
overall
average marks.
10) Show courses where the number of enrollments exceeds the average number of
enrollments
per course.