By the end of this lab, you will be able to: - Work with complex multi-table database schemas - Master JOIN operations (INNER, LEFT, RIGHT) - Use aggregate functions (COUNT, SUM, AVG, MAX, MIN) - Apply GROUP BY and HAVING clauses effectively - Write nested queries and subqueries - Understand set operations (UNION, INTERSECT) - Handle NULL values in queries
In this lab, we'll work with a university database containing information about students, courses, and enrollments. This realistic scenario will help you understand how databases are used in real-world applications.
Our database consists of three related tables: - Student: Contains student information (ID, name, GPA) - Course: Contains course details (ID, code, name, credit hours) - Enrolled: Links students to courses with grades (many-to-many relationship)
-- Clean slate: DROP existing DATABASE IF it EXISTS
DROP DATABASE IF EXISTS lab2;
CREATE DATABASE lab2;
USE lab2;
-- DROP TABLES IN correct ORDER (child TABLES first due to FOREIGN KEY constraints)
DROP TABLE IF EXISTS Enrolled; -- Junction TABLE (child)
DROP TABLE IF EXISTS Student; -- Parent TABLE
DROP TABLE IF EXISTS Course; -- Parent TABLE
-- CREATE Student TABLE
CREATE TABLE Student (
sid INT PRIMARY KEY, -- Student ID (UNIQUE identifier)
fname CHAR(20), -- First name (fixed LENGTH)
lname CHAR(20), -- Last name (fixed LENGTH)
gpa FLOAT -- Grade Point Average (can be NULL)
);
-- CREATE Course TABLE
CREATE TABLE Course (
cid INT PRIMARY KEY, -- Course ID (UNIQUE identifier)
code CHAR(10), -- Course code (e.g., "CS101")
name CHAR(40), -- Course name (e.g., "Intro to Programming")
credithours SMALLINT -- Credit hours (1-4 typically)
);
-- CREATE Enrolled TABLE (junction TABLE FOR many-to-many relationship)
CREATE TABLE Enrolled (
sid INT, -- Student ID (FOREIGN KEY)
cid INT, -- Course ID (FOREIGN KEY)
grade CHAR(2), -- Letter grade (A+, A, B+, etc.)
PRIMARY KEY (sid, cid), -- Composite PRIMARY KEY
FOREIGN KEY (sid) REFERENCES Student(sid), -- Link to Student TABLE
FOREIGN KEY (cid) REFERENCES Course(cid) -- Link to Course TABLE
);
Key Design Concepts:
- Composite Primary Key: (sid, cid) ensures one grade per student per course
- Foreign Key Constraints: Maintain referential integrity
- Many-to-Many Relationship: Students can enroll in multiple courses, courses can have multiple students
-- INSERT student records (SOME students have NULL GPA - NOT yet calculated)
INSERT INTO Student VALUES(1,'Amie','Massey',3.0);
INSERT INTO Student VALUES(2,'Abigail','Larsen',NULL);
INSERT INTO Student VALUES(3,'Cora','Rowland',4);
INSERT INTO Student VALUES(4,'Alesha','Ferrell',3.5);
INSERT INTO Student VALUES(5,'Nina','Lowery',NULL);
INSERT INTO Student VALUES(6,'Scarlet','Lane',2.6);
INSERT INTO Student VALUES(7,'Lukas','Reeves',3.6);
INSERT INTO Student VALUES(8,'Ray','Chang',3.2);
INSERT INTO Student VALUES(9,'Ioan','Reid',2.5);
INSERT INTO Student VALUES(10,'Ryan','Peck',3.1);
INSERT INTO Student VALUES(11,'Marco','Lowery',3.8);
INSERT INTO Student VALUES(12,'Pearl', 'Mayo',3.7);
INSERT INTO Student VALUES(13,'Elmer', 'Cain',2.7);
INSERT INTO Student VALUES(14,'Isla', 'Mccall',2.2);
INSERT INTO Student VALUES(15,'Kate', 'Kimmel',NULL);
Verify student data:
SELECT * FROM Student ORDER BY sid;
-- INSERT computer science courses WITH varying credit hours
INSERT INTO Course VALUES(1,'CS101', 'Computer Programming I',3);
INSERT INTO Course VALUES(2,'CS102', 'Computer Programming II',3);
INSERT INTO Course VALUES(3,'CS321', 'Data Structures',4);
INSERT INTO Course VALUES(4,'CS5710', 'Network',4);
INSERT INTO Course VALUES(5,'CS4550', 'DATABASE',4);
INSERT INTO Course VALUES(6,'CS5990', 'Capstone Project',4);
INSERT INTO Course VALUES(7,'CS6020', 'Data Mining',4);
Verify course data:
SELECT * FROM Course ORDER BY cid;
-- CS101 enrollments (ALL 15 students enrolled)
INSERT INTO Enrolled VALUES(1,1, 'A+');
INSERT INTO Enrolled VALUES(2,1, 'A-');
INSERT INTO Enrolled VALUES(3,1, 'B');
INSERT INTO Enrolled VALUES(4,1, 'C');
INSERT INTO Enrolled VALUES(5,1, 'D');
INSERT INTO Enrolled VALUES(6,1, 'A');
INSERT INTO Enrolled VALUES(7,1, 'B-');
INSERT INTO Enrolled VALUES(8,1, 'C+');
INSERT INTO Enrolled VALUES(9,1, 'D');
INSERT INTO Enrolled VALUES(10,1, 'C+');
INSERT INTO Enrolled VALUES(11,1, 'A-');
INSERT INTO Enrolled VALUES(12,1, 'A');
INSERT INTO Enrolled VALUES(13,1, 'B+');
INSERT INTO Enrolled VALUES(14,1, 'C+');
INSERT INTO Enrolled VALUES(15,1, 'A');
INSERT INTO Enrolled VALUES(1,2, 'A');
INSERT INTO Enrolled VALUES(2,2, 'C');
INSERT INTO Enrolled VALUES(3,2, 'B+');
INSERT INTO Enrolled VALUES(4,2, 'C-');
INSERT INTO Enrolled VALUES(5,2, 'D+');
INSERT INTO Enrolled VALUES(6,2, 'A-');
INSERT INTO Enrolled VALUES(7,2, 'C-');
INSERT INTO Enrolled VALUES(8,2, 'C');
INSERT INTO Enrolled VALUES(9,2, 'D+');
INSERT INTO Enrolled VALUES(10,2, 'C+');
INSERT INTO Enrolled VALUES(11,2, 'A-');
INSERT INTO Enrolled VALUES(12,2, 'A');
INSERT INTO Enrolled VALUES(13,2, 'B-');
INSERT INTO Enrolled VALUES(14,2, 'C');
INSERT INTO Enrolled VALUES (1,3,'C-');
INSERT INTO Enrolled VALUES (2,3,'B-');
INSERT INTO Enrolled VALUES (3,3,'D+');
INSERT INTO Enrolled VALUES (4,3,'C');
INSERT INTO Enrolled VALUES (5,3,'A+');
INSERT INTO Enrolled VALUES (6,3,'D+');
INSERT INTO Enrolled VALUES (7,3,'F');
INSERT INTO Enrolled VALUES (8,3,'A-');
INSERT INTO Enrolled VALUES (9,3,'D+');
INSERT INTO Enrolled VALUES (10,3,'D');
INSERT INTO Enrolled VALUES (11,3,'A+');
INSERT INTO Enrolled VALUES (12,3,'A');
INSERT INTO Enrolled VALUES (13,3,'B-');
INSERT INTO Enrolled VALUES (14,3,'C');
INSERT INTO Enrolled VALUES (15,3,'B-');
INSERT INTO Enrolled VALUES (1,4,'F');
INSERT INTO Enrolled VALUES (2,4,'A');
INSERT INTO Enrolled VALUES (3,4,'D-');
INSERT INTO Enrolled VALUES (4,4,'A-');
INSERT INTO Enrolled VALUES (5,4,'B-');
INSERT INTO Enrolled VALUES (6,4,'A-');
INSERT INTO Enrolled VALUES (7,4,'D+');
INSERT INTO Enrolled VALUES (8,4,'B+');
INSERT INTO Enrolled VALUES (9,4,'C+');
INSERT INTO Enrolled VALUES (10,4,'B');
INSERT INTO Enrolled VALUES (11,4,'F');
INSERT INTO Enrolled VALUES (12,4,'F');
INSERT INTO Enrolled VALUES (13,4,'A+');
INSERT INTO Enrolled VALUES (14,4,'A+');
INSERT INTO Enrolled VALUES (1,5,'A+');
INSERT INTO Enrolled VALUES (2,5,'A+');
INSERT INTO Enrolled VALUES (3,5,'B');
INSERT INTO Enrolled VALUES (4,5,'D+');
INSERT INTO Enrolled VALUES (5,5,'C-');
INSERT INTO Enrolled VALUES (6,5,'B-');
INSERT INTO Enrolled VALUES (7,5,'B');
INSERT INTO Enrolled VALUES (8,5,'B+');
INSERT INTO Enrolled VALUES (9,5,'A');
INSERT INTO Enrolled VALUES (10,5,'B');
INSERT INTO Enrolled VALUES (11,5,'D');
INSERT INTO Enrolled VALUES (12,5,'B');
INSERT INTO Enrolled VALUES (13,5,'B');
INSERT INTO Enrolled VALUES (14,5,'A+');
INSERT INTO Enrolled VALUES (1,6,'A+');
INSERT INTO Enrolled VALUES (2,6,'D');
INSERT INTO Enrolled VALUES (3,6,'D-');
INSERT INTO Enrolled VALUES (4,6,'C-');
INSERT INTO Enrolled VALUES (5,6,'C');
INSERT INTO Enrolled VALUES (6,6,'C-');
INSERT INTO Enrolled VALUES (7,6,'A-');
INSERT INTO Enrolled VALUES (8,6,'D');
INSERT INTO Enrolled VALUES (9,6,'B');
INSERT INTO Enrolled VALUES (10,6,'B-');
INSERT INTO Enrolled VALUES (11,6,'F');
INSERT INTO Enrolled VALUES (12,6,'C+');
INSERT INTO Enrolled VALUES (15,6,'F');
Verify enrollment data:
-- CHECK total enrollments
SELECT COUNT(*) AS total_enrollments FROM Enrolled;
-- See sample enrollments WITH student AND course names
SELECT s.fname, s.lname, c.code, c.name, e.grade
FROM Student s
JOIN Enrolled e ON s.sid = e.sid
JOIN Course c ON e.cid = c.cid
LIMIT 10;
Now that we have our database populated, let's practice various types of queries. Each exercise builds on previous concepts while introducing new techniques.
Problem: Find all students who received an 'A' or 'A+' in the Database course, ordered by their full name.
Analysis:
- We need data from all three tables:
- Student table: for student names
- Course table: to identify the Database course
- Enrolled table: for grades
- This requires joining three tables with two join conditions
Your Solution:
-- Write your query here
SELECT CONCAT(fname, ' ', lname) AS student_name
FROM Student s, Course c, Enrolled e
WHERE c.cid = e.cid
AND s.sid = e.sid
AND (e.grade = 'A+' OR e.grade = 'A')
AND c.name LIKE '%DATABASE%'
ORDER BY student_name;
SELECT CONCAT(s.fname, ' ', s.lname) AS student_name
FROM Student s
JOIN Enrolled e ON s.sid = e.sid
JOIN Course c ON e.cid = c.cid
WHERE (e.grade = 'A+' OR e.grade = 'A')
AND c.name LIKE '%DATABASE%'
ORDER BY student_name;
| student_name |
|---|
| Abigail Larsen |
| Amie Massey |
| Isla Mccall |
Find all countries that manufacture some product in the ‘Gadgets’ category. Assume you have the following data:
DROP TABLE IF EXISTS Company;
DROP TABLE IF EXISTS Product;
CREATE TABLE Product(
PName CHAR(20) PRIMARY KEY,
Price DOUBLE,
category CHAR(20),
Manufacturer CHAR(20)
);
CREATE TABLE Company(
CName CHAR(20) PRIMARY KEY,
StockPrice DOUBLE,
Country CHAR(20)
);
ALTER TABLE Product ADD FOREIGN KEY (Manufacturer) REFERENCES Company(CName);
INSERT INTO Company VALUES('GizmoWorks',25,'USA');
INSERT INTO Company VALUES('Canon',65,'Japan');
INSERT INTO Company VALUES('Hitachi',15, 'Japan');
INSERT INTO Product VALUES('Gizmo',19.99,'Gadgets','GizmoWorks');
INSERT INTO Product VALUES('Powergizmo',29.99,'Gadgets','GizmoWorks');
INSERT INTO Product VALUES('SingleTouch',149.99,'Photography','Canon');
INSERT INTO Product VALUES('MultiTouch',203.99,'Household','Hitachi');
SELECT Country FROM Product, Company
WHERE Manufacturer=CName AND Category='Gadgets'
This would return: Country USA USA How to get USA only once.
Prepare the database as follows:
DROP TABLE IF EXISTS R;
DROP TABLE IF EXISTS T;
DROP TABLE IF EXISTS S;
CREATE TABLE R(A INT);
CREATE TABLE S(A INT);
CREATE TABLE T(A INT);
INSERT INTO R VALUES (1);
INSERT INTO R VALUES (1);
INSERT INTO R VALUES (2);
INSERT INTO R VALUES (3);
INSERT INTO R VALUES (5);
INSERT INTO R VALUES (7);
INSERT INTO R VALUES (7);
INSERT INTO R VALUES (8);
INSERT INTO S VALUES (1);
INSERT INTO S VALUES (1);
INSERT INTO S VALUES (2);
INSERT INTO S VALUES (3);
INSERT INTO T VALUES (1);
INSERT INTO T VALUES (2);
INSERT INTO T VALUES (3);
INSERT INTO T VALUES (7);
Run this query
SELECT DISTINCT R.A
FROM R, S, T
WHERE R.A=S.A OR R.A=T.A
This would return the following
| A |
|---|
| 1 |
| 2 |
| 3 |
| 7 |
Remove all tuples from S
SET SQL_SAFE_UPDATES = 0;
DELETE FROM S;
SET SQL_SAFE_UPDATES = 1;
MySQL has something called safe mode, to disable it. We run SET SQL_SAFE_UPDATES = 0; and to enable it again SET SQL_SAFE_UPDATES = 1; Rerun the query
SELECT DISTINCT R.A
FROM R, S, T
WHERE R.A=S.A OR R.A=T.A
MySQL does not have INTERSECT or EXCEPT keyword. In the next lecture, we will explain an alternative. Compare these two queries:
SELECT R.A
FROM R, S
WHERE R.A=S.A
UNION
SELECT R.A
FROM R, T
WHERE R.A=T.A
SELECT R.A
FROM R, S
WHERE R.A=S.A
UNION ALL
SELECT R.A
FROM R, T
WHERE R.A=T.A
DROP TABLE IF EXISTS Product;
DROP TABLE IF EXISTS Company;
CREATE TABLE Product(
PName CHAR(20) PRIMARY KEY,
maker CHAR(20),
factory_loc CHAR(20)
);
CREATE TABLE Company(
CName CHAR(20) PRIMARY KEY,
hq_city CHAR(20)
);
ALTER TABLE Product ADD FOREIGN KEY (maker) REFERENCES Company(CName);
INSERT INTO Company VALUES('X co.','Seattle');
INSERT INTO Company VALUES('Y inc.','Seattle');
INSERT INTO Company VALUES('A co.', 'Tokyo');
INSERT INTO Product VALUES('X','X co.','US');
INSERT INTO Product VALUES('A','A co.','China');
INSERT INTO Product VALUES('A+','A co.','US');
INSERT INTO Product VALUES('Y','Y inc.','China');
Compare the three queries below:
SELECT hq_city
FROM Company, Product
WHERE maker = cname
AND factory_loc='US'
AND hq_city IN (
SELECT hq_city
FROM Company, Product
WHERE maker = cname
AND factory_loc='China'
);
SELECT maker, hq_city
FROM Company, Product
WHERE maker = cname
AND factory_loc='US'
AND (maker,hq_city) IN (
SELECT maker, hq_city
FROM Company, Product
WHERE maker = cname
AND factory_loc='China'
);
SELECT DISTINCT hq_city
FROM Company, Product
WHERE maker = cname
AND cname IN (
SELECT maker
FROM Product
WHERE factory_loc = 'US')
AND cname IN (
SELECT maker
FROM Product
WHERE factory_loc = 'China');
To disable safe updates or delete
SET SQL_SAFE_UPDATES=0;
To enable them back
SET SQL_SAFE_UPDATES=0;
Run the following query
SELECT DISTINCT hq_city
FROM Company, Product
WHERE maker = cname
AND cname IN (
SELECT maker
FROM Product
WHERE factory_loc = 'US')
AND cname IN (
SELECT maker
FROM Product
WHERE factory_loc = 'China')
To understand the previous query, you may break it into three parts.
Q1:
SELECT maker
FROM Product
WHERE factory_loc = 'US'
SELECT maker
FROM Product
WHERE factory_loc = 'China'
Q3:
SELECT *
FROM Company, Product
WHERE maker = cname
Another way:
SELECT DISTINCT hq_city
FROM Company, (SELECT maker
FROM Product
WHERE factory_loc = 'US') US,
(SELECT maker
FROM Product
WHERE factory_loc = 'China') Ch
WHERE us.maker = cname
AND ch.maker= cname
Another one:
SELECT DISTINCT hq_city
FROM Company, Product p1, Product p2
WHERE p1.maker = cname
AND p2.maker= cname
AND p1.factory_loc = 'US'
AND p2.factory_loc = 'China';
DROP TABLE IF EXISTS company;
DROP TABLE IF EXISTS Product;
DROP TABLE IF EXISTS Purchase;
CREATE TABLE Company (
cname CHAR(20) PRIMARY KEY,
city CHAR(20)
);
CREATE TABLE Product (
pname CHAR(20) ,
maker CHAR(20),
price DOUBLE,
FOREIGN KEY (maker) REFERENCES company(cname),
PRIMARY KEY (pname, maker)
);
CREATE TABLE Purchase
(id INT PRIMARY KEY,
product CHAR(20),
buyer VARCHAR(30),
FOREIGN KEY (product) REFERENCES Product(pname)
);
INSERT INTO Company VALUES('X co','Seattle');
INSERT INTO Company VALUES('Y co','Jeffersonville');
INSERT INTO Company VALUES('A co','Seattle');
INSERT INTO Company VALUES('A inc','LA');
INSERT INTO Company VALUES('B co','NYC');
INSERT INTO Product VALUES('X','X co',20);
INSERT INTO Product VALUES('X+','X co',10);
INSERT INTO Product VALUES('Y','Y co',5);
INSERT INTO Product VALUES('A','A co',8);
INSERT INTO Product VALUES('T','A co',18);
INSERT INTO Product VALUES('A','A inc',5);
INSERT INTO Product VALUES('AA','A co',30);
INSERT INTO Product VALUES('AAA','A co',20);
INSERT INTO Product VALUES('B','B co',8);
INSERT INTO Purchase VALUES(1,'A','Joe Blow');
INSERT INTO Purchase VALUES(2,'A','Joe Smith');
INSERT INTO Purchase VALUES(3,'A','John Oliver');
INSERT INTO Purchase VALUES(4,'A','John Oliver');
INSERT INTO Purchase VALUES(5,'Y','Joe Blow');
INSERT INTO Purchase VALUES(6,'X','Joe Blow');
INSERT INTO Purchase VALUES(7,'A','Joe Blow');
INSERT INTO Purchase VALUES(8,'A','Joe Blow');
INSERT INTO Purchase VALUES(9,'A','Joe Blow');
Cities where one can find companies that manufacture products bought by "Joe Blow”.
SELECT c.city
FROM Company c
WHERE c.cname IN (
SELECT pr.maker
FROM Purchase p, Product pr
WHERE p.product = pr.pname
AND p.buyer = 'Joe Blow')
Note that we got Seattle twice for X co and A co
SELECT c.city
FROM Company c,
Product p,
Purchase pu
WHERE c.cname = p.maker
AND p.pname = pu.product
AND pu.buyer = 'Joe Blow'
Compare the previous two queries.
Find products that are more expensive than all those produced by “X co”
SELECT pname
FROM Product
WHERE price > ALL(
SELECT price
FROM Product
WHERE maker = 'X co')
Find ‘copycat’ products, i.e. products made by competitors with the same names as products made by ‘A co’
SELECT p1.pname
FROM Product p1
WHERE p1.maker = 'A co'
AND EXISTS(
SELECT p2.pname
FROM Product p2
WHERE p2.maker <> 'A co'
AND p1.pname = p2.pname)
DROP TABLE Purchase;
CREATE TABLE Purchase (
product CHAR(20),
pdate DATE,
price DOUBLE,
quantity INT
);
INSERT INTO Purchase VALUES('bagel','2021-10-21',1,20);
INSERT INTO Purchase VALUES('banana','2021-10-3',0.5,10);
INSERT INTO Purchase VALUES('banana','2021-10-10',1,10);
INSERT INTO Purchase VALUES('bagel','2021-10-25',1.5,20);
Note that we do not have a primary key.
Get the number of purchases.
sql
SELECT COUNT(*) FROM purchase
Find the sales after ‘10/10/2021’
SELECT product,
SUM(price * quantity) AS TotalSales
FROM Purchase
WHERE pdate > '2021-10-10'
GROUP BY product
SELECT DISTINCT x.product,
(SELECT SUM(y.price*y.quantity)
FROM Purchase y WHERE x.product = y.product AND y.pdate > '2021-10-10') TotalSales FROM Purchase x WHERE x.pdate > '2021-10-10'
Same query as before, except that we consider only products that have more than 100 buyers
sql
SELECT product, SUM(price*quantity)
FROM Purchase
WHERE pdate > '2021-10-1'
GROUP BY product
HAVING SUM(quantity) > 100
Purchase
| Id | Product | Price | Quantity |
|---|---|---|---|
| 1 | bagel | 1.0 | 5 |
| 2 | banana | 0.5 | 6 |
| 3 | Juice | 1.0 | 4 |
| 4 | donuts | 1.5 | 8 |
| 5 | bagel | 1.5 | 7 |
| 6 | banana | 1.0 | 4 |
| 7 | banana | 1.0 | 3 |
| 8 | juice | 3.0 | 5 |
DROP TABLE IF EXISTS Purchase;
CREATE TABLE Purchase (
ID INT PRIMARY KEY AUTO_INCREMENT,
Product CHAR(20),
Price DECIMAL(10,2),
Quantity INT
);
INSERT INTO Purchase(Product, Price, Quantity) VALUES('bagel',1.0,5),
('banana',.5,6), ('juice',1.0,4),
('donuts', 1.5,8), ('bagel', 1.5,7),
('banana',1.0,4),('banana',1,3), ('juice',3.0,5)
;
NOTE: AUTO_INCREMENT, and how we insert into the table.
SELECT SUM(Price*Quantity) AS Total_sales
FROM Purchase
WHERE product='bagel'
| Id | Product | Price | Quantity |
|---|---|---|---|
| 1 | bagel | 1.0 | 5 |
| 5 | bagel | 1.5 | 7 |
| Price | X | Quantity |
|---|---|---|
| 1.0 | x | 5 |
| 1.5 | x | 7 |
| 15.5 |
Run the following two queries:
SELECT COUNT(*)
FROM Purchase;
SELECT COUNT(DISTINCT product)
FROM Purchase;
First query returns 8 while the second returns 4.
The following query finds the total number of units sold across all products.
SELECT SUM(Quantity)
FROM Purchase
The query returns 36. To find the number of units sold for each product.
SELECT Product, SUM(Quantity)
FROM Purchase
GROUP BY Product
Find products and sales that have sold more than 10 units.
SELECT Product, SUM(Quantity*Price)
FROM Purchase
GROUP BY Product
HAVING SUM(Quantity)> 10
| Product | SUM(Quantity*Price) |
|---|---|
| bagel | 15.50 |
| banana | 10.00 |
Find the product with the most units sold.
SELECT Product, SUM(Quantity*Price)
FROM Purchase
GROUP BY Product
HAVING SUM(Quantity)= (
SELECT MAX(t.units)
FROM
(SELECT SUM(Quantity) AS units
FROM Purchase
GROUP BY Product) t
);
To understand the query, let us start with:
SELECT SUM(Quantity)
FROM Purchase
GROUP BY Product
SELECT MAX(t.units)
FROM (SELECT SUM(Quantity) AS units
FROM Purchase
GROUP BY Product) t
The query above finds the maximum of the total unit sold.
Run the following queries, to create the schema:
DROP TABLE IF EXISTS product;
DROP TABLE IF EXISTS supplier;
CREATE TABLE supplier(
id INT,
sname VARCHAR(30) NOT NULL,
PRIMARY KEY (id),
UNIQUE(sname)
);
CREATE TABLE product(
id INT PRIMARY KEY,
pname VARCHAR(30) NOT NULL,
price FLOAT,
supplierid INT,
FOREIGN KEY (supplierid) REFERENCES supplier(id)
);
Insert Data
INSERT INTO supplier(id, sname) VALUES (1, 'bike Ltd');
INSERT INTO supplier(id, sname) VALUES (2, 'bike USA');
INSERT INTO supplier(id, sname) VALUES (3, 'bikes4all');
INSERT INTO product VALUES (1,'girl bike', 110, 1);
INSERT INTO product VALUES (2,'boy bike', 110, 2);
INSERT INTO product VALUES (3,'mountain bike', 510, 2);
INSERT INTO product VALUES (4,'bike', 180, NULL );
INSERT INTO product VALUES (5,'ebike', 280, NULL );
Try to insert the following
INSERT INTO supplier(id, sname) VALUES (4, 'bike Ltd');
The previous SQL insert should not work, as we have specified that the supplier name to be unique.
Q1:
Find all products with unknown supplier.
A supplier of a product is recorded in product table to find out products with unknown supplier, we need to find those that are NULL.
SELECT * FROM product WHERE supplierid IS NULL
Q2: Find all suppliers with no product listed.
SELECT * FROM Supplier s
WHERE NOT EXISTS (SELECT * FROM product p
WHERE p.supplierid=s.id)
SELECT * FROM product p
LEFT OUTER JOIN supplier s
ON p.supplierid=s.id;
Q4: Find supplier (along with the supplied products)
SELECT * FROM product p
RIGHT OUTER JOIN supplier s
ON p.supplierid=s.id;
Q5 Find supplier and products including not matched
SELECT * FROM product p
full OUTER JOIN supplier s
ON p.supplierid=s.id;
SELECT * FROM product p
LEFT OUTER JOIN supplier s
ON p.supplierid=s.id
UNION
SELECT * FROM product p
RIGHT OUTER JOIN supplier s
ON p.supplierid=s.id;
CREATE TABLE student (SID INT PRIMARY KEY,Name VARCHAR(10),Major
VARCHAR(4));
CREATE TABLE enrolled (SID INT,cid VARCHAR(5),PRIMARY KEY
(sid,cid));
INSERT INTO student VALUES (40,'alex','cs'), (41, 'john','cs'), (42, 'mat', 'cs'), (43, 'zack', 'math');
INSERT INTO Enrolled VALUES (40,'cs101'),(40, 'cs102'),(41, 'cs101'),(41, 'cs404'),(41,'cs405'), (42,'cs101'),(42,'cs102'),(42,'cs203'),(43,'cs101'),(43,'cs102');
SELECT DISTINCT NAME FROM STUDENT S WHERE major='cs’ AND NOT EXISTS
(SELECT * FROM ENROLLED E2 WHERE SID=40 AND CID NOT IN (SELECT CID
FROM ENROLLED E WHERE E.SID=S.SID) )
SELECT DISTINCT NAME FROM STUDENT S WHERE major=‘cs’ AND NOT EXISTS
(SELECT * FROM ENROLLED E2 WHERE SID=40 AND NOT EXISTS ( SELECT *
FROM ENROLLED E WHERE E.SID=S.SID AND E2.CID=E.CID) )