0% found this document useful (0 votes)
215 views

Basic SQL Queries On PostgreSQL

The document demonstrates basic SQL queries on sample tables. It shows how to create and drop databases and tables, perform INSERT, SELECT, UPDATE and DELETE operations, add constraints and indexes. Specific queries demonstrated include selecting rows, counts, averages, maximums and sums. It also shows cascading deletes across multiple tables.

Uploaded by

Ashish Reddy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
215 views

Basic SQL Queries On PostgreSQL

The document demonstrates basic SQL queries on sample tables. It shows how to create and drop databases and tables, perform INSERT, SELECT, UPDATE and DELETE operations, add constraints and indexes. Specific queries demonstrated include selecting rows, counts, averages, maximums and sums. It also shows cascading deletes across multiple tables.

Uploaded by

Ashish Reddy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

Basic SQL Queries

/* Basic SQL Queries */


postgres=# \l country-# select * from saleslist;
postgres=# drop database country; sales
DROP DATABASE -------
postgres=# drop table country; 90000
DROP TABLE 50000
postgres=# create database country; 30000
CREATE DATABASE 75000
postgres=# \c country (4 rows)
You are now connected to database "country" as country-# drop view saleslist;
user "postgres". DROP VIEW
country-# country-# drop table country;
CREATE TABLE country ( DROP TABLE
division varchar(80) primary key, /* Demonstrate ON DELETE CASCADE - I */
sales int postgres=# create database weather;
); postgres=# \c weather;
CREATE TABLE weather=# CREATE TABLE cities (
country-# \d city varchar(80) primary key,
country-# INSERT INTO country VALUES location point
('north',90000); );
INSERT 0 1 weather=# CREATE TABLE weather (
country-# INSERT INTO country VALUES city varchar(80) references cities(city)
('south',50000); ON DELETE CASCADE,
INSERT 0 1 temp_lo int,
country-# INSERT INTO country VALUES temp_hi int,
('east',30000); prcp real,
INSERT 0 1 date date
country-# INSERT INTO country VALUES );
('west',75000); INSERT INTO cities VALUES ('Berkeley','(4,12)');
INSERT 0 1 INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0,
country-# INSERT INTO country VALUES '1994-11-28');
('west',88000); INSERT INTO cities VALUES ('Tenali','(6,4)');
ERROR: duplicate key value violates unique INSERT INTO weather VALUES ('Tenali', 24, 35, 0.0,
constraint "country_pkey" '2017-12-20');
DETAIL: Key (division)=(west) already exists. select * from cities;
country-# select * from country; city | location
division | sales ----------+----------
----------+------- Berkeley | (4,12)
north | 90000 Tenali | (6,4)
south | 50000 (2 rows)
east | 30000 select * from weather;
west | 75000 city | temp_lo | temp_hi | prcp | date
(4 rows) ----------+---------+---------+------+------------
country-# select sales from country; Berkeley | 45 | 53 | 0 | 1994-11-28
sales Tenali | 24 | 35 | 0 | 2017-12-20
------- (2 rows)
90000 delete from weather where city ='Tenali';
50000 select * from weather;
30000 city | temp_lo | temp_hi | prcp | date
75000 ----------+---------+---------+------+------------
(4 rows) Berkeley | 45 | 53 | 0 | 1994-11-28
country-# select count(*) from country; (1 row)
count INSERT INTO weather VALUES ('Tenali', 24, 35, 0.0,
------- '2017-12-20');
4 select * from weather;
(1 row) city | temp_lo | temp_hi | prcp | date
country-# select avg(sales) from country; ----------+---------+---------+------+------------
avg Berkeley | 45 | 53 | 0 | 1994-11-28
-------------------- Tenali | 24 | 35 | 0 | 2017-12-20
61250.000000000000 (2 rows)
(1 row) delete from cities where city ='Tenali';
country-# select max(sales) from country; select * from cities;
max city | location
------- ----------+----------
90000 Berkeley | (4,12)
(1 row) (1 row)
country-# select sum(sales) from country; select * from weather;
sum city | temp_lo | temp_hi | prcp | date
-------- ----------+---------+---------+------+------------
245000 Berkeley | 45 | 53 | 0 | 1994-11-28
(1 row) (1 row)
country-# create view saleslist as select sales /* Demonstrate ON DELETE CASCADE - II*/
from country;
CREATE VIEW

Vishnuvardhan Mannava 1
Basic SQL Queries
CREATE TABLE so_headers ( CREATE TABLE so_items (
id serial PRIMARY KEY, item_id int4 NOT NULL,
customer_id int8, so_id int4 REFERENCES so_headers(id) ON DELETE CASCADE,
ship_to VARCHAR (255) product_id int4,
); qty int4,
net_price numeric,
PRIMARY KEY (item_id,so_id)
);
INSERT INTO so_headers VALUES (1,10,'Ithanagar, 4-25-17, Tenali, 522201, India');
INSERT INTO so_headers VALUES (2,20,'North Street, 1900, CA, 95134, USA');
INSERT INTO so_headers VALUES (3,10,'South Street, 1400, CA, 95134, USA');
select * from so_headers; INSERT INTO so_items VALUES (1,1,1001,2,1000);
id | customer_id | ship_to INSERT INTO so_items VALUES (2,1,1000,3,1500);
----+-------------+----------------------------------------- INSERT INTO so_items VALUES (3,2,1000,4,1500);
INSERT INTO so_items VALUES (1,2,1001,5,1000);
1 | 10 | Ithanagar, 4-25-17, Tenali, 522201, India
INSERT INTO so_items VALUES (2,3,1002,2,1700);
2 | 20 | North Street, 1900, CA, 95134, USA INSERT INTO so_items VALUES (3,3,1003,1,2000);
3 | 10 | South Street, 1400, CA, 95134, USA
(3 rows)
select * from so_items; delete from so_headers where id =1;
item_id | so_id | product_id | qty | net_price select * from so_items;
---------+-------+------------+-----+----------- item_id | so_id | product_id | qty | net_price
1 | 1 | 1001 | 2 | 1000 ---------+-------+------------+-----+-----------
2 | 1 | 1000 | 3 | 1500 3 | 2 | 1000 | 4 | 1500
3 | 2 | 1000 | 4 | 1500 1 | 2 | 1001 | 5 | 1000
1 | 2 | 1001 | 5 | 1000 2 | 3 | 1002 | 2 | 1700
2 | 3 | 1002 | 2 | 1700 3 | 3 | 1003 | 1 | 2000
3 | 3 | 1003 | 1 | 2000 (4 rows)
(6 rows)
salesorder=# alter table so_items drop column so_id;
ALTER TABLE
salesorder=# alter table so_items add column so_id int4 REFERENCES so_headers(id) ON DELETE RESTRICT;
ALTER TABLE
delete from so_items where so_id =1;
DELETE 0
salesorder=# select * from so_items;
item_id | product_id | qty | net_price | so_id
---------+------------+-----+-----------+-------
3 | 1000 | 4 | 1500 |
1 | 1001 | 5 | 1000 |
2 | 1002 | 2 | 1700 |
3 | 1003 | 1 | 2000 |
(4 rows)
/* Sailors Database, drop tables if exists. */
drop table Reserves;
drop table Sailors;
drop table Boats;
create database sailors;
\c sailors;
\dt Sailors;
/* create tables according to the definition chapter 5.1(Raghu Ramakrishnan, Johannes Gehrke, Database
Management Systems, Third Edition */
sailors=# select * from Sailors; sailors=# select * from Boats; sailors=# select * from Reserves;
sid | sname | rating | age bid | bname | color sid | bid | day
-----+----------+--------+------ -----+-----------+------- -----+-----+------------
22 | Dustin | 7 | 45.0 101 | Interlake | blue 22 | 101 | 1998-10-10
29 | Brutus | 1 | 33.0 102 | Interlake | red 22 | 102 | 1998-10-10
31 | Lubber | 8 | 55.5 103 | Clipper | green 22 | 103 | 1998-10-08
32 | Andy | 8 | 25.5 104 | Marine | red 22 | 104 | 1998-10-07
58 | Rusty | 10 | 35.0 (4 rows) 31 | 102 | 1998-11-10
64 | Horataio | 7 | 35.0 31 | 103 | 1998-11-06
71 | Zorba | 10 | 16.0 31 | 104 | 1998-11-12
74 | Horataio | 9 | 35.0 64 | 101 | 1998-09-05
85 | Art | 3 | 25.5 64 | 102 | 1998-09-08
95 | Bob | 3 | 63.5 74 | 103 | 1998-09-08
(10 rows) (10 rows)
create table Sailors(
sid int not null constraint sailors_pk primary key,
sname varchar(20),
rating int,
age decimal(4,1)
);
create table Boats(
bid int not null constraint boat_pk primary key,
bname varchar(20),
color varchar(20)
);

Vishnuvardhan Mannava 2
Basic SQL Queries
create table Reserves(
sid int,
bid int,
day date,
primary key (sid,bid,day),
foreign key (sid) references Sailors(sid) ON DELETE CASCADE,
foreign key (bid) references Boats(bid) ON DELETE CASCADE
);
\d Sailors;
/* initilize the tables as Fig 5.1-5.3, NOTE the order, how about insert reserves before sailors? */
insert into Sailors (sid,sname,rating,age) values(22,'Dustin',7,45.0);
insert into Sailors (sid,sname,rating,age) values(29,'Brutus',1,33.0);
insert into Sailors (sid,sname,rating,age) values(31,'Lubber',8,55.5);
insert into Sailors (sid,sname,rating,age) values(32,'Andy',8,25.5);
insert into Sailors (sid,sname,rating,age) values(58,'Rusty',10,35.0);
insert into Sailors (sid,sname,rating,age) values(64,'Horataio',7,35.0);
insert into Sailors (sid,sname,rating,age) values(71,'Zorba',10,16.0);
insert into Sailors (sid,sname,rating,age) values(74,'Horataio',9,35.0);
insert into Sailors (sid,sname,rating,age) values(85,'Art',3,25.5);
insert into Sailors (sid,sname,rating,age) values(95,'Bob',3,63.5);
insert into Boats (bid,bname,color) values(101,'Interlake','blue');
insert into Boats (bid,bname,color) values(102,'Interlake','red');
insert into Boats (bid,bname,color) values(103,'Clipper','green');
insert into Boats (bid,bname,color) values(104,'Marine','red');
insert into Reserves(sid,bid,day) values(22,101,'10-OCT-98');
insert into Reserves(sid,bid,day) values(22,102,'10-OCT-98');
insert into Reserves(sid,bid,day) values(22,103,'8-OCT-98');
insert into Reserves(sid,bid,day) values(22,104,'7-OCT-98');
insert into Reserves(sid,bid,day) values(31,102,'10-Nov-98');
insert into Reserves(sid,bid,day) values(31,103,'6-NOV-98');
insert into Reserves(sid,bid,day) values(31,104,'12-NOV-98');
insert into Reserves(sid,bid,day) values(64,101,'5-SEP-98');
insert into Reserves(sid,bid,day) values(64,102,'8-SEP-98');
insert into Reserves(sid,bid,day) values(74,103,'8-SEP-98');
/* Q1 "Find the names of sailors who have reserved boat number 103" */
SELECT S.sname /*Nested Query*/ /* Correlated Nested Queries */
FROM Sailors S, Reserves R SELECT S.sname SELECT S.sname
WHERE S.sid = R.Sid AND FROM Sailors S FROM Sailors S
R.bid = 103; WHERE S.sid IN (SELECT R.sid WHERE EXISTS (SELECT *
FROM Reserves R FROM Reserves R
WHERE R.bid = 103); WHERE R.bid = 103
AND R.sid = S.sid);
sname sname sname
---------- --------- ---------
Dustin Dustin Brutus
Lubber Dustin Andy
Horataio Dustin Rusty
(3 rows) Lubber Horataio
Lubber Zorba
Horataio Art
Horataio Bob
(7 rows) (7 rows)
/*"Find the names of sailors who have never reserved boat number 103"*/
/* which of the following is right? */
SELECT S.sname SELECT S.sname
FROM Sailors S, Reserves R FROM Sailors S
WHERE S.sid = R.Sid AND R.bid != 103; WHERE S.sid NOT IN (SELECT R.sid
FROM Reserves R
WHERE R.bid = 103);
/* Q2 "Find the names of sailors who have reserved a red boat"*/
SELECT S.sname /* Nested Query */
FROM Sailors S, Reserves R, Boats B SELECT S.sname
WHERE S.sid = R.sid AND R.bid = B.bid AND FROM Sailors S
B.color = 'red'; WHERE S.sid IN (SELECT R.sid
FROM Reserves R
WHERE R.bid IN(SELECT B.bid
FROM Boats B
WHERE B.color ='red'));
sname Lubber sname
--------- Lubber ----------
Dustin Horataio Horataio
Dustin (5 rows) Dustin
Lubber
(3 rows)
/* Q3 "Find the colors of boats reserved by Lubber" */
SELECT B.color color

Vishnuvardhan Mannava 3
Basic SQL Queries
FROM Sailors S, Reserves R, Boats B -------
WHERE S.sid = R.sid AND R.bid = B.bid AND S.sname ='Lubber'; red
green
red
(3 rows)
/* Q4 "Find the names of sailors who have reserved at least one boat" */
SELECT S.sname SELECT DISTINCT S.sname
FROM Sailors S, Reserves R FROM Sailors S, Reserves R
WHERE S.sid = R.sid ; WHERE S.sid = R.sid;
/* Q5 "Find the names of sailors who have reserved a red or a green boat" */
SELECT S.sname SELECT S.sname
FROM Sailors S, Reserves R, Boats B FROM Sailors S, Reserves R, Boats B
WHERE S.sid = R.sid AND R.bid=B.bid AND WHERE S.sid = R.sid AND R.bid = B.bid AND
(B.color='red' OR B.color='green'); B.color='red'
UNION
sname
SELECT S2.sname
----------
FROM Sailors S2, Boats B2, Reserves R2
Dustin
WHERE S2.sid = R2.sid AND R2.bid = B2.bid AND
Dustin
B2.color = 'green';
Dustin
sname
Lubber
----------
Lubber
Lubber
Lubber
Horataio
Horataio
Dustin
Horataio
(3 rows)
(8 rows)
/* Q6 "Find the names of sailors who have reserved both a red and a green boat" */
SELECT S.sname SELECT S.sname
FROM Sailors S, Reserves R1, Boats B1, Reserves R2, FROM Sailors S, Reserves R, Boats B
Boats B2 WHERE S.sid = R.sid AND R.bid = B.bid AND B.color =
WHERE S.sid = R1.sid AND R1.bid = B1.bid 'red'
AND S.sid = R2.sid AND R2.bid = B2.bid INTERSECT
AND B1.color = 'red' AND B2.color = 'green'; SELECT S2.sname
sname FROM Sailors S2, Boats B2, Reserves R2
-------- WHERE S2.sid = R2.sid AND R2.bid = B2.bid AND
Dustin B2.color= 'green';
Dustin sname
Lubber ----------
Lubber Lubber
(4 rows) Horataio
Dustin
(3 rows)
/* Nested Query */
SELECT S.sname sname
FROM Sailors S, Reserves R, Boats B --------
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color ='red' Dustin
AND S.sid IN (SELECT S2.sid Dustin
FROM Sailors S2, Boats B2, Reserves R2 Lubber
WHERE S2.sid = R2.sid AND R2.bid = B2.bid Lubber
AND B2.color ='green'); (4 rows)
/* Q "Find the names of sailors who have reserved a red but not a green boat" */
/* Oracle does not have EXCEPT but use keyword MINUS.*/
/* when we run the examples in our textbook, we should change EXCEPT to MINUS.*/
SELECT S.sname sname
FROM Sailors S, Reserves R, Boats B -------
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color = 'red' (0 rows)
EXCEPT
SELECT S2.sname
FROM Sailors S2, Boats B2, Reserves R2
WHERE S2.sid = R2.sid AND R2.bid = B2.bid AND B2.color= 'green';
SELECT S.sname sname
FROM Sailors S, Reserves R, Boats B ----------
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color ='red' Horataio
AND S.sid NOT IN (SELECT S2.sid (1 row)
FROM Sailors S2, Boats B2, Reserves R2
WHERE S2.sid = R2.sid AND R2.bid = B2.bid
AND B2.color ='green');

/* Q7 "Find the names of sailors who have reserved at least two different boats" */
SELECT DISTINCT S.sname sname
FROM Sailors S, Reserves R1, Reserves R2 ----------
WHERE S.sid = R1.sid AND R1.sid = R2.sid AND R1.bid != R2.bid; Horataio
Lubber
Dustin
(3 rows)
/* "Find the names of sailors who have reserved at least n boats"
Vishnuvardhan Mannava 4
Basic SQL Queries
THE SAME IDEA IS TO JOIN N RELATIONS --- TOO DEDIOUS
We can do this by combining CNT, GROUP BY, and nested query together.
The question is how we can do this before we address GROUP BY.
Assume one dbms does not support GROUP BY and HAVING, how will you help them implement this?
HINT: the same relation equijoin many times.
IS THERE ANY DIFFERENCE BETWEEN THE TWO FOLLOWING EXPRESSION?
IS the next one the same as the above one?
INSERT INTO Reserves values(74,103,'08-DEC-98'); */
SELECT S.sname sname sname SELECT S1.sname
from Sailors S, Reserves R ---------- ---------- FROM Sailors S1
where S.sid = R.sid Horataio Dustin WHERE S1.sid IN (
GROUP BY S.sname Lubber Lubber SELECT S.sid
HAVING COUNT(*) > 1; Dustin Horataio from Sailors S, Reserves R
(3 rows) (3 rows) where S.sid = R.sid
GROUP BY S.sid
HAVING COUNT(*) > 1);
/* IF YOU RUN THE TWO EXPRESSION OVER THE CURRENT INSTANCE, NO DIFFERENCE BETWEEN THE RESULT */
/* HOW ABOUT WE INSERT TWO NEW TUPLES, CHECK THE DIFFERENCE. */
/* insert into Sailors (sid,sname,rating,age) values(131,'Lubber',8,55.5);
insert into Reserves(sid,bid,day) values(131,101,'8-OCT-98'); */
/* Q8 "Find the sids of silors with age over 20 who have not reserved a red boat" */
/* Q9 "Find the names of sailors who have reserved all boats" */
SELECT S.sname /* HINT: for each sailor we check that there is no boat that
FROM Sailors S has not been reserved by this sailor */
WHERE NOT EXISTS((SELECT B.bid SELECT S.sname
FROM Boats B ) FROM Sailors S
EXCEPT WHERE NOT EXISTS (SELECT B.bid
(SELECT R.bid FROM Boats B
FROM Reserves R WHERE NOT EXISTS(SELECT R.bid
WHERE R.sid = S.sid)); FROM Reserves R
sname WHERE R.bid = B.bid
-------- AND R.sid = S.sid));
Dustin
(1 row)
/* Q10 "Find the names of sailors who have reserved all boats called Interlake" */
SELECT S.sname sname
FROM Sailors S ----------
WHERE NOT EXISTS (SELECT B.bid Dustin
FROM Boats B Horataio
WHERE B.bname ='Interlake' AND (2 rows)
NOT EXISTS(SELECT R.bid
FROM Reserves R
WHERE R.bid = B.bid
AND R.sid = S.sid));
/* Q11 "Find all sailors with a rating above 7" */
SELECT S.sid, S.sname, S.rating, S.age sid | sname | rating | age
FROM Sailors S -----+----------+--------+------
WHERE S.rating > 7; 31 | Lubber | 8 | 55.5
32 | Andy | 8 | 25.5
58 | Rusty | 10 | 35.0
71 | Zorba | 10 | 16.0
74 | Horataio | 9 | 35.0
(5 rows)
/* Q12 "Find the names and ages of sailors with a rating above 7" */
SELECT S.Sname, S.age sname | age
FROM Sailors S ----------+------
WHERE S.rating > 7; Lubber | 55.5
Andy | 25.5
Rusty | 35.0
Zorba | 16.0
Horataio | 35.0
(5 rows)
/* Q13 "Find the sailor name boat id and reservation date for each reservation" */
/* Q14 "Find sailors who have reserved all red boats" */
/* Q15 "Find the names and ages of all sailors"*/
SELECT DISTINCT S.sname, S.age sname | age Dustin | 45.0
FROM Sailors S; ----------+------ Bob | 63.5
Rusty | 35.0 Art | 25.5
Horataio | 35.0 Andy | 25.5
Lubber | 55.5 Brutus | 33.0
Zorba | 16.0 (9 rows)
/* Q16 "Find the sids of sailors who have reserved a red boat"; */
SELECT R.sid sid
FROM Boats B, Reserves R -----
WHERE B.bid = R.bid AND B.color = 'red'; 22
Vishnuvardhan Mannava 5
Basic SQL Queries
22
31
31
64
(5 rows)
/* Q17 "Compute increments for the ratings of persons who have sailed two different
boats on the same day" */
SELECT S.sname, S.rating +1 AS rating sname | rating
FROM Sailors S, Reserves R1, Reserves R2 --------+--------
WHERE S.sid = R1.sid AND S.sid = R2.sid Dustin | 8
AND R1.day = R2.day AND R1.bid <> R2.bid; Dustin | 8
(2 rows)
/* Q18 Find the ages of sailors whose name begins and ends with B and has at least
three characters */
SELECT S.age age
FROM Sailors S -----
WHERE S.sname LIKE 'B_%B'; (0 rows)
/*Q19 Find the sids of all sailors who have reserved red boats but not green boats */
SELECT S.sid SELECT R.sid
FROM Sailors S, Reserves R, Boats B FROM Boats B, Reserves R
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color = 'red' WHERE R.bid = B.bid AND B.color = 'red'
EXCEPT EXCEPT
SELECT S2.sid SELECT R2.sid
FROM Sailors S2, Reserves R2, Boats B2 FROM Boats B2, Reserves R2
WHERE S2.sid = R2.sid AND R2.bid = B2.bid AND B2.color WHERE R2.bid = B2.bid AND B2.color =
='green'; 'green';
sid sid
----- -----
64 64
(1 row) (1 row)
/*Q20 "Find all sids of sailors who have a rating of 10 or have reserved boat 104" */
SELECT S.sid sid
FROM Sailors S -----
WHERE S.rating = 10 22
UNION 31
SELECT R.sid 58
FROM Reserves R 71
WHERE R.bid = 104; (4 rows)
/* Q21 "Find the names of sailors who have not reserved a red boat" */
SELECT S.sname sname
FROM Sailors S ----------
WHERE S.sid NOT IN (SELECT R.sid Brutus
FROM Reserves R Andy
WHERE R.bid IN (SELECT B.bid Rusty
FROM Boats B Zorba
WHERE B.color='red')); Horataio
Art
Bob
(7 rows)
/* Q22 "Find sailors whose rating is better than some sailor called Horatio" */
/* SET comparison operators */ sid
SELECT S.sid -----
FROM Sailors S (0 rows) Wrong!!!
WHERE S.rating > ANY(SELECT S2.rating
FROM Sailors S2
WHERE S2.sname = 'Horatio');
/* Q23 "Find sailors whose rating is better than every sailor called Horatio" */
SELECT S.sid sid 64
FROM Sailors S ----- 71
WHERE S.rating > ALL(SELECT S2.rating 22 74
FROM Sailors S2 29 85
WHERE S2.sname = 'Horatio'); 31 95
32 (10 rows)
58
/* Q24 "Find the sailors with the highest rating" */
SELECT S.sid sid
FROM Sailors S -----
WHERE S.rating >= ALL(SELECT S2.rating FROM Sailors S2); 58
71
(2 rows)
/* Q25 "Find the average of all sailors" */
SELECT AVG (S.age) avg
FROM Sailors S; ---------------------
36.9000000000000000
Vishnuvardhan Mannava 6
Basic SQL Queries
(1 row)
/* Q26 "Find the average age of sailors with a rating of 10"*/
SELECT AVG(S.age) avg
FROM Sailors S ---------------------
WHERE S.rating = 10; 25.5000000000000000
(1 row)
/* Q27 "Find the name and age of the oldest sailor" */
/* This query is illegal in SQL-- of the SELECT clause uses an aggregate operation, then it must use
only aggregate operations unless the query contains a GROUP By clause. */
SELECT S.sname, MAX(S.age) SELECT S.sname, S.age
FROM Sailors S; FROM Sailors S
WHERE S.age = (SELECT MAX(S2.age)
FROM Sailors S2);
Error !!! sname | age
-------+------
Bob | 63.5
(1 row)
/* the following is legal in SQL92 but may not be supported in many systems - Oracle support */
SELECT S.sname, S.age
FROM Sailors S
WHERE (SELECT MAX(S2.age)
FROM Sailors S2) = S.age ;
/* Q28 "Count the number of sailors" */
SELECT COUNT(*) count
FROM Sailors S; -------
10
(1 row)
/* Q29 "Count the number of different sailor names" */
SELECT COUNT (DISTINCT S.sname) count
FROM Sailors S; -------
9
(1 row)
/* Q30 "Find the names of sailors who are older than the oldest sailor with a rating
of 10" */
SELECT S.sname sname SELECT S.sname
FROM Sailors S -------- FROM Sailors S
WHERE S.age > (SELECT MAX(S2.age) Dustin WHERE S.age > ALL (SELECT S2.age
FROM Sailors S2 Lubber FROM Sailors S2
WHERE S2.rating = 10); Bob WHERE S2.rating = 10);
(3 rows)
/* Q31 "Find the age of the youngest sailor for each rating level" */
rating | min /* SELECT MIN(S.age) FROM Sailors S SELECT S.rating, MIN(S.age)
--------+------ WHERE S.rating = i; */ FROM Sailors S
7 | 35.0 GROUP BY S.rating ;
9 | 35.0
10 | 16.0
3 | 25.5
1 | 33.0
8 | 25.5
(6 rows)
/* Q32 "Find the age of the youngest sailor who is eligible to vote(i.e., is at least
18 years old)for each rating level with at least two such sailors" */
SELECT S.rating, MIN(S.age) AS minage rating | minage
FROM Sailors S --------+--------
WHERE S.age >=18 7 | 35.0
GROUP BY S.rating 3 | 25.5
HAVING COUNT(*) > 1; 8 | 25.5
(3 rows)
/* Q33 "For each red boat, find the number of reservations for this boat" */
SELECT B.bid, COUNT(*) AS sailorcount bid | sailorcount
FROM Boats B, Reserves R -----+-------------
WHERE R.bid = B.bid AND B.color = 'red' 102 | 3
GROUP BY B.bid; 104 | 2
(2 rows)
/* the following is illegal for only columns that appear in the group by clause can appear in the having
clause, unless they appear as arguments to an aggregate operator in the having clause. */
SELECT B.bid, COUNT(*) AS sailorcount bid | sailorcount
FROM Boats B, Reserves R -----+-------------
WHERE R.bid = B.bid 102 | 3
GROUP BY B.bid 104 | 2
HAVING B.color ='red' ; (2 rows)
/* Q34 "Find the average age of sailors for each rating level that has at least two
sailors" */
Vishnuvardhan Mannava 7
Basic SQL Queries
SELECT S.rating, AVG(S.age) SELECT S.rating, AVG (S.age) AS average rating | average
AS average FROM Sailors S --------+---------------------
FROM Sailors S GROUP BY S.rating 7 | 40.0000000000000000
GROUP BY S.rating HAVING 1 < (SELECT COUNT(*) 10 | 25.5000000000000000
HAVING COUNT(*) > 1; FROM Sailors S2 3 | 44.5000000000000000
WHERE S.rating = S2.rating); 8 | 40.5000000000000000
(4 rows)
/* Q35 "Find the average age of sailors who are of voting age(i.e., at least 18 years
old) for each rating level that has at least two sailors" */
SELECT S.rating, AVG(S.age) AS average rating | average
FROM Sailors S --------+---------------------
WHERE S.age >=18 7 | 40.0000000000000000
GROUP BY S.rating 10 | 35.0000000000000000
HAVING 1 <(SELECT COUNT(*) 3 | 44.5000000000000000
FROM Sailors S2 8 | 40.5000000000000000
WHERE S.rating = S2.rating); (4 rows)
/* Q36 "Find the average age of sailors who are of voting age(i.e., at least 18 years
old)for each rating level that has at least two such sailors" */
SELECT S.rating, AVG(S.age) AS average SELECT S.rating, AVG(S.age) AS average
FROM Sailors S FROM Sailors S
WHERE S.age > 18 WHERE S.age > 18
GROUP BY S.rating GROUP BY S.rating
HAVING 1<(SELECT COUNT(*) HAVING COUNT(*) > 1;
FROM Sailors S2
WHERE S.rating=S2.rating AND S2.age>=18);
rating | average rating | average
--------+--------------------- --------+---------------------
7 | 40.0000000000000000 7 | 40.0000000000000000
3 | 44.5000000000000000 3 | 44.5000000000000000
8 | 40.5000000000000000 8 | 40.5000000000000000
(3 rows) (3 rows)
/* Q37 "Find those rating sfor which the average age of sailors in the minimum
overall ratings" */
/* SELECT S.rating SELECT Temp.rating, Temp.average
FROM Sailors S FROM (SELECT S.rating, AVG(S.age) AS average
WHERE AVG(S.age) = (SELECT MIN(AVG(S2.age)) FROM Sailors S
FROM Sailors S2 GROUP BY S.rating) AS Temp
GROUP BY S2.rating); */ WHERE Temp.average = (SELECT MIN(Temp.average) FROM
Temp);
ERROR: aggregate functions are not allowed in ERROR: relation "temp" does not exist
WHERE
/* How about the following, is it the same as the above? */
SELECT Temp.rating, MIN(Temp.average) /* One student figures out the following approach as all the
FROM (SELECT S.rating, AVG(S.age) AS above do not work in oracle.
average, CREATE VIEW Temp(Rating,Average) AS
FROM Sailors S (SELECT S.rating, AVG(S.age)
GROUP BY S.rating) AS Temp FROM Sailors S
GROUP BY Temp.rating; GROUP BY S.rating) ;
SELECT Temp.Rating,Temp.Average
FROM Temp
WHERE Temp.Average = (SELECT MIN(Temp.Average) FROM Temp) ;
drop view Temp;
ERROR: syntax error at or near "FROM" rating | average
--------+---------------------
10 | 25.5000000000000000
(1 row)
/* New Query "find the sailor ids with top 5 rating ranks." */
SELECT sid, rating
FROM ( SELECT sid, rating, RANK() OVER (ORDER BY rating DESC) rating_rank FROM sailors )
WHERE rating_rank <= 5;
ERROR: subquery in FROM must have an alias
/* Company database SQL data definition. Ordering of tables is important since a table can
reference tables that are defined before. Create all six empty tables of Company database */
-- create a new empty table department
create table department
( dname varchar(15) not null,
dnumber int not null,
mgrssn char(9) not null,
mgrstartdate char(10),
constraint deptpk primary key (dnumber),
constraint deptsk unique (dname)
/*constraint deptmgrfk foreign key (mgrssn) references employee(ssn),This foreign key has been commented
out since the dbms does not support mutual foreign keys between department and employee tables */
);

Vishnuvardhan Mannava 8
Basic SQL Queries
-- create a new empty table employee
create table employee
( fname varchar(15) not null,
minit char,
lname varchar(15) not null,
ssn char(9) not null,
bdate char(10),
address varchar(30),
sex char,
salary decimal(10,2),
superssn char(9),
dno int not null,
constraint emppk primary key (ssn),
/*constraint empsuperfk foreign key (superssn) references employee(ssn), This foreign key constraint
among columns of the same table has not been supported by most SQL systems */
constraint empdeptfk foreign key (dno) references department(dnumber)
);
-- create a new empty table dept_locations
create table dept_locations
( dnumber int not null,
dlocation varchar(15) not null,
constraint dlocpk primary key (dnumber, dlocation),
constraint dlocdeptfk foreign key (dnumber) references department(dnumber)
);
-- create a new empty table project
create table project
( pname varchar(15) not null,
pnumber int not null,
plocation varchar(15),
dnum int not null,
constraint projpk primary key (pnumber),
constraint projsk unique (pname),
constraint projdeptfk foreign key (dnum) references department(dnumber)
);
-- create a new empty table works_on
create table works_on
( essn char(9) not null,
pno int not null,
hours decimal(3,1) not null,
constraint workpk primary key (essn, pno),
constraint workempfk foreign key (essn) references employee(ssn),
constraint workprojfk foreign key (pno) references project(pnumber)
);
-- create a new empty table dependent
create table dependent
( essn char(9) not null,
dependent_name varchar(15) not null,
sex char,
bdate char(10),
relationship varchar(8),
constraint deppk primary key (essn, dependent_name),
constraint depempfk foreign key (essn) references employee(ssn)
);
/* Add rows of data to each of these six empty tables of Company DB */
-- Insertion of three department rows
INSERT INTO department VALUES ('Research','5','333445555','1988-05-22');
INSERT INTO department VALUES ('Administration','4','987654321','1995-01-01');
INSERT INTO department VALUES ('Headquarters','1','888665555','1981-06-19');
-- Insertion of eight employee rows
INSERT INTO employee VALUES
('James','E','Borg','888665555','1937-11-10','450 Stone, Houston, TX','M','55000','','1');
INSERT INTO employee VALUES
('Franklin','T','Wong','333445555','1955-12-08','638 Voss, Houston, TX','M','40000','888665555','5');
INSERT INTO employee VALUES
('Jennifer','S','Wallace','987654321','1941-06-20','291 Berry, Bellaire, TX','F','43000','888665555','4');
INSERT INTO employee VALUES
('John','B','Smith','123456789','1965-01-09','731 Fondren, Houston, TX','M','30000','333445555','5 ');
INSERT INTO employee VALUES
('Ramesh','K','Narayan','666884444','1962-09-15','975 Fire Oak,Humble, TX','M','38000','333445555','5');
INSERT INTO employee VALUES
('Joyce','A','English','453453453','1972-07-31','5631 Rice, Houston, TX','F','25000','333445555','5');
INSERT INTO employee VALUES
('Alicia','J','Zelaya','999887777','1968-01-19','3321 Castle, Spring, TX','F','25000','987654321','4');
INSERT INTO employee VALUES
('Ahmad','V','Jabbar','987987987','1969-03-29','980 Dallas, Houston, TX','M','25000','987654321','4');
-- Insertion of five dept_locations rows

Vishnuvardhan Mannava 9
Basic SQL Queries
INSERT INTO dept_locations VALUES ('1','Houston');
INSERT INTO dept_locations VALUES ('4','Stafford');
INSERT INTO dept_locations VALUES ('5','Bellaire');
INSERT INTO dept_locations VALUES ('5','Sugarland');
INSERT INTO dept_locations VALUES ('5','Houston');
-- Insertion of six project rows
INSERT INTO project VALUES ('ProductX','1','Bellaire','5');
INSERT INTO project VALUES ('ProductY','2','Sugarland','5');
INSERT INTO project VALUES ('ProductZ','3','Houston','5');
INSERT INTO project VALUES ('Computerization','10','Stafford','4');
INSERT INTO project VALUES ('Reorganization','20','Houston','1');
INSERT INTO project VALUES ('Newbenefits','30','Stafford','4');
-- Insertion of sixteen works_on rows
INSERT INTO works_on VALUES ('123456789','1','32.5');
INSERT INTO works_on VALUES ('123456789','2','7.5');
INSERT INTO works_on VALUES ('666884444','3','40.0');
INSERT INTO works_on VALUES ('453453453','1','20.0');
INSERT INTO works_on VALUES ('453453453','2','20.0');
INSERT INTO works_on VALUES ('333445555','2','10.0');
INSERT INTO works_on VALUES ('333445555','3','10.0');
INSERT INTO works_on VALUES ('333445555','10','10.0');
INSERT INTO works_on VALUES ('333445555','20','10.0');
INSERT INTO works_on VALUES ('999887777','30','30.0');
INSERT INTO works_on VALUES ('999887777','10','10.0');
INSERT INTO works_on VALUES ('987987987','10','35.0');
INSERT INTO works_on VALUES ('987987987','30','5.0');
INSERT INTO works_on VALUES ('987654321','30','20.0');
INSERT INTO works_on VALUES ('987654321','20','15.0');
INSERT INTO works_on VALUES ('888665555','20','0.0');
-- Insertion of seven dependent rows
INSERT INTO dependent VALUES ('333445555','Alice','F','1986-04-05','daughter');
INSERT INTO dependent VALUES ('333445555','Theodore','M','1983-10-25','son');
INSERT INTO dependent VALUES ('333445555','Joy','F','1958-05-03','spouse');
INSERT INTO dependent VALUES ('987654321','Abner','M','1942-02-28','spouse');
INSERT INTO dependent VALUES ('123456789','Michael','M','1988-01-04','son');
INSERT INTO dependent VALUES ('123456789','Alice','F','1988-12-30','daughter');
INSERT INTO dependent VALUES ('123456789','Elizabeth','F','1967-05-05','spouse');
/* End of Company database script */
company=# select * from department; company=# select * from dept_locations;
dname | dnumber | mgrssn | mgrstartdate dnumber | dlocation
----------------+---------+-----------+-------------- ---------+-----------
Research | 5 | 333445555 | 1988-05-22 1 | Houston
Administration | 4 | 987654321 | 1995-01-01 4 | Stafford
Headquarters | 1 | 888665555 | 1981-06-19 5 | Bellaire
(3 rows) 5 | Sugarland
5 | Houston
(5 rows)
company=# select * from employee;
fname | minit | lname | ssn | bdate | address | sex | salary | superssn | dno
----------+-------+---------+-----------+------------+--------------------------+-----+----------+-----------+-----
James | E | Borg | 888665555 | 1937-11-10 | 450 Stone, Houston, TX | M | 55000.00 | | 1
Franklin | T | Wong | 333445555 | 1955-12-08 | 638 Voss, Houston, TX | M | 40000.00 | 888665555 | 5
Jennifer | S | Wallace | 987654321 | 1941-06-20 | 291 Berry, Bellaire, TX | F | 43000.00 | 888665555 | 4
John | B | Smith | 123456789 | 1965-01-09 | 731 Fondren, Houston, TX | M | 30000.00 | 333445555 | 5
Ramesh | K | Narayan | 666884444 | 1962-09-15 | 975 Fire Oak, Humble, TX | M | 38000.00 | 333445555 | 5
Joyce | A | English | 453453453 | 1972-07-31 | 5631 Rice, Houston, TX | F | 25000.00 | 333445555 | 5
Alicia | J | Zelaya | 999887777 | 1968-01-19 | 3321 Castle, Spring, TX | F | 25000.00 | 987654321 | 4
Ahmad | V | Jabbar | 987987987 | 1969-03-29 | 980 Dallas, Houston, TX | M | 25000.00 | 987654321 | 4
(8 rows)
company=# select * from project; company=# select * from works_on;
pname | pnumber | plocation | dnum essn | pno | hours
-----------------+---------+-----------+------ -----------+-----+-------
ProductX | 1 | Bellaire | 5 123456789 | 1 | 32.5
ProductY | 2 | Sugarland | 5 123456789 | 2 | 7.5
ProductZ | 3 | Houston | 5 666884444 | 3 | 40.0
Computerization | 10 | Stafford | 4 453453453 | 1 | 20.0
Reorganization | 20 | Houston | 1 453453453 | 2 | 20.0
Newbenefits | 30 | Stafford | 4 333445555 | 2 | 10.0
(6 rows) 333445555 | 3 | 10.0
company=# select * from dependent; 333445555 | 10 | 10.0
essn | dependent_name | sex | bdate | relationship 333445555 | 20 | 10.0
-----------+----------------+-----+------------+-------------- 999887777 | 30 | 30.0
333445555 | Alice | F | 1986-04-05 | daughter 999887777 | 10 | 10.0
333445555 | Theodore | M | 1983-10-25 | son 987987987 | 10 | 35.0
333445555 | Joy | F | 1958-05-03 | spouse 987987987 | 30 | 5.0
987654321 | Abner | M | 1942-02-28 | spouse 987654321 | 30 | 20.0
123456789 | Michael | M | 1988-01-04 | son 987654321 | 20 | 15.0
123456789 | Alice | F | 1988-12-30 | daughter 888665555 | 20 | 0.0

Vishnuvardhan Mannava 10
Basic SQL Queries
123456789 | Elizabeth | F | 1967-05-05 | spouse (16 rows)
(7 rows)
Query 0: Retrieve the birthdate and address of the employee whose name is 'John B.
Smith'.
SELECT BDATE, ADDRESS bdate | address
FROM EMPLOYEE ------------+--------------------------
WHERE FNAME='John' AND MINIT='B’ AND LNAME='Smith’; 1965-01-09 | 731 Fondren, Houston, TX
(1 row)
Query 1: Retrieve the name and address of all employees who work for the 'Research'
department.
SELECT FNAME, LNAME, ADDRESS /* NESTING OF QUERIES */
FROM EMPLOYEE, DEPARTMENT SELECT FNAME, LNAME, ADDRESS
WHERE DNAME='Research' AND DNUMBER=DNO; FROM EMPLOYEE
fname | lname | address WHERE DNO IN
----------+---------+-------------------------- (SELECT DNUMBER
Franklin | Wong | 638 Voss, Houston, TX FROM DEPARTMENT
John | Smith | 731 Fondren, Houston, TX WHERE DNAME='Research' );
Ramesh | Narayan | 975 Fire Oak, Humble, TX
Joyce | English | 5631 Rice, Houston, TX
(4 rows)
SELECT FNAME, LNAME, ADDRESS SELECT FNAME, LNAME, ADDRESS
FROM (EMPLOYEE JOIN DEPARTMENT FROM (EMPLOYEE NATURAL JOIN DEPARTMENT
ON DNUMBER=DNO) AS DEPT(DNAME, DNO, MSSN, MSDATE)
WHERE DNAME='Research’; WHERE DNAME='Research’;
Query 2: For every project located in 'Stafford', list the project number, the controlling department
number, and the department manager's last name, address, and birthdate.
SELECT PNUMBER, DNUM, LNAME, BDATE, ADDRESS SELECT PNUMBER, DNUM, LNAME, BDATE, ADDRESS
FROM PROJECT, DEPARTMENT, EMPLOYEE FROM (PROJECT JOIN DEPARTMENT ON DNUM=DNUMBER)JOIN
WHERE DNUM=DNUMBER AND MGRSSN=SSN AND EMPLOYEE ON MGRSSN=SSN
PLOCATION='Stafford'; WHERE PLOCATION='Stafford’
pnumber | dnum | lname | bdate | address
---------+------+---------+------------+-------------------------
30 | 4 | Wallace | 1941-06-20 | 291 Berry, Bellaire, TX
10 | 4 | Wallace | 1941-06-20 | 291 Berry, Bellaire, TX
(2 rows)
Query 3: Retrieve the name of each employee who works on all the projects controlled
by department number 5.
SELECT FNAME, LNAME This operator was dropped from the language, possibly
FROM EMPLOYEE because of the difficulty in implementing it efficiently
WHERE ( (SELECT PNO FROM WORKS_ON WHERE Most implementations of SQL do not have this operator
SSN=ESSN) The CONTAINS operator compares two sets of values, and
CONTAINS returns TRUE if one set contains all values in the other
(SELECT PNUMBER FROM PROJECT WHERE DNUM=5) ); set

Query 4: Make a list of all project numbers for projects that involve an employee
whose last name is 'Smith' as a worker or as a manager of the department that
controls the project.
(SELECT PNAME pname
FROM PROJECT, DEPARTMENT, EMPLOYEE ----------
WHERE DNUM=DNUMBER AND MGRSSN=SSN AND ProductX
LNAME='Smith') ProductY
UNION (2 rows)
(SELECT PNAME
FROM PROJECT, WORKS_ON, EMPLOYEE
WHERE PNUMBER=PNO AND
ESSN=SSN AND LNAME='Smith')
Query 6: Retrieve the names of employees who have no dependents.
SELECT FNAME, LNAME fname | lname
FROM EMPLOYEE --------+---------
WHERE NOT EXISTS (SELECT * James | Borg
FROM DEPENDENT Ramesh | Narayan
WHERE SSN=ESSN); Joyce | English
Alicia | Zelaya
Ahmad | Jabbar
(5 rows)
Query 8: For each employee, retrieve the employee's name, and the name of his or her
immediate supervisor.
SELECT E.FNAME, E.LNAME, S.FNAME, S.LNAME SELECT E.FNAME, E.LNAME, S.FNAME, S.LNAME
FROM EMPLOYEE AS E, EMPLOYEE AS S FROM (EMPLOYEE E LEFT OUTER JOIN
WHERE E.SUPERSSN=S.SSN EMPLOYEE S ON E.SUPERSSN=S.SSN);
fname | lname | fname | lname fname | lname | fname | lname
----------+---------+----------+--------- ----------+---------+----------+---------
Franklin | Wong | James | Borg James | Borg | |
Jennifer | Wallace | James | Borg Franklin | Wong | James | Borg
Vishnuvardhan Mannava 11
Basic SQL Queries
John | Smith | Franklin | Wong Jennifer | Wallace | James | Borg
Ramesh | Narayan | Franklin | Wong John | Smith | Franklin | Wong
Joyce | English | Franklin | Wong Ramesh | Narayan | Franklin | Wong
Alicia | Zelaya | Jennifer | Wallace Joyce | English | Franklin | Wong
Ahmad | Jabbar | Jennifer | Wallace Alicia | Zelaya | Jennifer | Wallace
(7 rows) Ahmad | Jabbar | Jennifer | Wallace
(8 rows)
Query 9: Retrieve the SSN values for all employees.
SELECT SSN SELECT SSN, DNAME
FROM EMPLOYEE; FROM EMPLOYEE, DEPARTMENT;
/* If more than one relation is specified in the FROM-clause and there is no join condition, then the
CARTESIAN PRODUCT of tuples is selected. It is extremely important not to overlook specifying any
selection and join conditions in the WHERE-clause; otherwise, incorrect and very large relations may
result*/
SELECT * SELECT * SELECT DISTINCT SALARY
FROM EMPLOYEE FROM EMPLOYEE, DEPARTMENT FROM EMPLOYEE;
WHERE DNO=5; WHERE DNAME='Research' AND DNO=DNUMBER;

Query 12: Retrieve the name of each employee who has a dependent with the same first
name as the employee.
SELECT E.FNAME, E.LNAME fname | lname
FROM EMPLOYEE AS E -------+-------
WHERE E.SSN IN (0 rows)
(SELECT ESSN
FROM DEPENDENT
WHERE ESSN=E.SSN AND
E.FNAME=DEPENDENT_NAME);
Query 13: Retrieve the social security numbers of all employees who work on project
number 1, 2, or 3.
SELECT DISTINCT ESSN essn
FROM WORKS_ON -----------
WHERE PNO IN (1, 2, 3); 453453453
123456789
333445555
666884444
(4 rows)
Query 14: Retrieve the names of all employees who do not have supervisors.
SELECT FNAME, LNAME fname | lname
FROM EMPLOYEE -------+-------
WHERE SUPERSSN IS NULL; (0 rows)
Query 15: Find the maximum salary, the minimum salary, and the average salary among
all employees.
SELECT MAX(SALARY), MIN(SALARY), AVG(SALARY) max | min | avg
FROM EMPLOYEE; ----------+----------+--------------------
55000.00 | 25000.00 | 35125.000000000000
(1 row)
Query 16: Find the maximum salary, the minimum salary, and the average salary among
employees who work for the 'Research' department.
SELECT MAX(SALARY), MIN(SALARY), AVG(SALARY) max | min | avg
FROM EMPLOYEE, DEPARTMENT ----------+----------+--------------------
WHERE DNO=DNUMBER AND 40000.00 | 25000.00 | 33250.000000000000
DNAME='Research'; (1 row)
Queries 17 and 18: Retrieve the total number of employees in the company (Q17), and
the number of employees in the 'Research' department (Q18).
SELECT COUNT (*) SELECT COUNT (*)
FROM EMPLOYEE; FROM EMPLOYEE, DEPARTMENT
WHERE DNO=DNUMBER AND
DNAME='Research’;
count count
------- -------
8 4
(1 row) (1 row)
Query 20: For each department, retrieve the department number, the number of
employees in the department, and their average salary.
SELECT DNO, COUNT (*), AVG (SALARY) dno | count | avg
FROM EMPLOYEE -----+-------+--------------------
GROUP BY DNO; 5 | 4 | 33250.000000000000
1 | 1 | 55000.000000000000
4 | 3 | 31000.000000000000
(3 rows)
Query 21: For each project, retrieve the project number, project name, and the number
of employees who work on that project.
SELECT PNUMBER, PNAME, COUNT (*) pnumber | pname | count
Vishnuvardhan Mannava 12
Basic SQL Queries
FROM PROJECT, WORKS_ON ---------+-----------------+-------
WHERE PNUMBER=PNO 3 | ProductZ | 2
GROUP BY PNUMBER, PNAME; 1 | ProductX | 2
30 | Newbenefits | 3
2 | ProductY | 3
10 | Computerization | 3
20 | Reorganization | 3
(6 rows)
Query 22: For each project on which more than two employees work, retrieve the
project number, project name, and the number of employees who work on that project.
SELECT PNUMBER, PNAME, COUNT(*) pnumber | pname | count
FROM PROJECT, WORKS_ON ---------+-----------------+-------
WHERE PNUMBER=PNO 30 | Newbenefits | 3
GROUP BY PNUMBER, PNAME 2 | ProductY | 3
HAVING COUNT (*) > 2; 10 | Computerization | 3
20 | Reorganization | 3
(4 rows)
Query 25: Retrieve all employees whose address is in Houston, Texas. Here, the value
of the ADDRESS attribute must contain the substring 'Houston,TX‘ in it.
SELECT FNAME, LNAME fname | lname
FROM EMPLOYEE ----------+---------
WHERE ADDRESS LIKE James | Borg
'%Houston, TX%'; Franklin | Wong
John | Smith
Joyce | English
Ahmad | Jabbar
(5 rows)
Query 26: Retrieve all employees who were born during the 1950s.
/* Here, '5' must be the 8th character of the string (according to our format for date), so the BDATE
value is '_______5_', with each underscore as a place holder for a single arbitrary character.*/
SELECT FNAME, LNAME fname | lname
FROM EMPLOYEE ----------+-------
WHERE BDATE LIKE '__5_______’; Franklin | Wong
(1 row)
Query 27: Show the effect of giving all employees who work on the 'ProductX' project
a 10% raise.
SELECT FNAME, LNAME, 1.1*SALARY fname | lname | ?column?
FROM EMPLOYEE, WORKS_ON, -------+---------+-----------
PROJECT John | Smith | 33000.000
WHERE SSN=ESSN AND PNO=PNUMBER Joyce | English | 27500.000
AND PNAME='ProductX’; (2 rows)
Query 28: Retrieve a list of employees and the projects each works in, ordered by the
employee's department, and within each department ordered alphabetically by employee
last name.
SELECT DNAME, LNAME, FNAME, PNAME dname | lname | fname | pname
FROM DEPARTMENT, EMPLOYEE, ----------------+---------+----------+-----------------
WORKS_ON, PROJECT Administration | Jabbar | Ahmad | Computerization
WHERE DNUMBER=DNO AND SSN=ESSN Administration | Jabbar | Ahmad | Newbenefits
AND PNO=PNUMBER Administration | Wallace | Jennifer | Reorganization
ORDER BY DNAME, LNAME Administration | Wallace | Jennifer | Newbenefits
Administration | Zelaya | Alicia | Computerization
Administration | Zelaya | Alicia | Newbenefits
Headquarters | Borg | James | Reorganization
Research | English | Joyce | ProductY
Research | English | Joyce | ProductX
Research | Narayan | Ramesh | ProductZ
Research | Smith | John | ProductX
Research | Smith | John | ProductY
Research | Wong | Franklin | Reorganization
Research | Wong | Franklin | Computerization
Research | Wong | Franklin | ProductZ
Research | Wong | Franklin | ProductY
(16 rows)
Default Values
When a new row is created and no values are specified for some of the columns, those columns will be filled with their respective default values. In a table
definition, default values are listed after the column data type. For example:
CREATE TABLE products ( CREATE TABLE products (
product_no integer, product_no integer DEFAULT
name text, nextval('products_product_no_seq'),
price numeric DEFAULT 9.99 ...
); );
CREATE TABLE products (
product_no SERIAL,
...
Vishnuvardhan Mannava 13
Basic SQL Queries
);
Constraints
To that end, SQL allows you to define constraints on columns and tables. Constraints give you as much control over the data in your tables as you wish. If a
user attempts to store data in a column that would violate a constraint, an error is raised. This applies even if the value came from the default value
definition.
Check Constraints
CREATE TABLE products ( CREATE TABLE products (
product_no integer, product_no integer,
name text, name text,
price numeric CHECK (price > 0) price numeric CONSTRAINT positive_price CHECK (price > 0)
); );
CREATE TABLE products ( Names can be assigned to table constraints in the same way as column constraints:
product_no integer, CREATE TABLE products (
name text, product_no integer,
price numeric CHECK (price > 0), name text,
discounted_price numeric CHECK price numeric,
(discounted_price > 0), CHECK (price > 0),
CHECK (price > discounted_price) discounted_price numeric,
); CHECK (discounted_price > 0),
CONSTRAINT valid_discount CHECK (price > discounted_price)
);
Not-Null Constraints
CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric NOT NULL CHECK (price > 0)
);
Unique Constraints
CREATE TABLE products ( CREATE TABLE example (
product_no integer UNIQUE, a integer,
name text, b integer,
price numeric c integer,
); UNIQUE (a, c)
);
To define a unique constraint for a group of columns, write it as a table constraint with the column names separated by commas: You can assign your own
name for a unique constraint, in the usual way:
CREATE TABLE products (
product_no integer CONSTRAINT must_be_different UNIQUE,
name text,
price numeric
);
Primary Keys
A primary key constraint indicates that a column, or group of columns, can be used as a unique identifier for rows in the table. This requires that the values
be both unique and not null. So, the following two table definitions accept the same data:
CREATE TABLE products ( CREATE TABLE products (
product_no integer UNIQUE NOT NULL, product_no integer PRIMARY KEY,
name text, name text,
price numeric price numeric
); );
Primary keys can span more than one column; the syntax is similar to unique constraints:
CREATE TABLE example (
a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
);
Foreign Keys
A foreign key constraint specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. We say
this maintains the referential integrity between two related tables. Say you have the product table that we have used several times already: Let's also assume
you have a table storing orders of those products. We want to ensure that the orders table only contains orders of products that actually exist. So we define a
foreign key constraint in the orders table that references the products table:
CREATE TABLE orders ( You can also shorten the above command to:
order_id integer PRIMARY KEY, CREATE TABLE orders (
product_no integer REFERENCES products(product_no), order_id integer PRIMARY KEY,
quantity integer product_no integer REFERENCES products,
); quantity integer
);
Now it is impossible to create orders with non-NULL product_no entries that do not appear in the products table. We say that in this situation the orders
table is the referencing table and the products table is the referenced table. Similarly, there are referencing and referenced columns. because in absence of a
column list the primary key of the referenced table is used as the referenced column(s).
A foreign key can also constrain and reference a group of columns. As usual, it then needs to be written in table constraint form. Here is a contrived syntax
example:
CREATE TABLE t1 (
a integer PRIMARY KEY,

Vishnuvardhan Mannava 14
Basic SQL Queries
b integer,
c integer,
FOREIGN KEY (b, c) REFERENCES other_table (c1, c2)
);
Of course, the number and type of the constrained columns need to match the number and type of the referenced columns. You can assign your own name
for a foreign key constraint, in the usual way. A table can have more than one foreign key constraint. This is used to implement many-to-many relationships
between tables. Say you have tables about products and orders, but now you want to allow one order to contain possibly many products (which the structure
above did not allow). You could use this table structure:
CREATE TABLE products ( CREATE TABLE order_items (
product_no integer PRIMARY KEY, product_no integer REFERENCES products,
name text, order_id integer REFERENCES orders,
price numeric quantity integer,
); PRIMARY KEY (product_no, order_id)
CREATE TABLE orders ( );
order_id integer PRIMARY KEY,
shipping_address text,
...
);
Notice that the primary key overlaps with the foreign keys in the last table. We know that the foreign keys disallow creation of orders that do not relate to
any products. But what if a product is removed after an order is created that references it? SQL allows you to handle that as well. Intuitively, we have a few
options:
• Disallow deleting a referenced product
• Delete the orders as well
• Something else?
To illustrate this, let's implement the following policy on the many-to-many relationship example above: when someone wants to remove a product that is
still referenced by an order (via order_items), we disallow it. If someone removes an order, the order items are removed as well:
CREATE TABLE products ( CREATE TABLE order_items (
product_no integer PRIMARY KEY, product_no integer REFERENCES products ON
name text, DELETE RESTRICT,
price numeric order_id integer REFERENCES orders ON DELETE
); CASCADE,
CREATE TABLE orders ( quantity integer,
order_id integer PRIMARY KEY, PRIMARY KEY (product_no, order_id)
shipping_address text, );
...
);
Restricting and cascading deletes are the two most common options. RESTRICT prevents deletion of a referenced row. NO ACTION means that if any
referencing rows still exist when the constraint is checked, an error is raised; this is the default behavior if you do not specify anything. (The essential
difference between these two choices is that NO ACTION allows the check to be deferred until later in the transaction, whereas RESTRICT does not.)
CASCADE specifies that when a referenced row is deleted, row(s) referencing it should be automatically deleted as well. There are two other options: SET
NULL and SET DEFAULT. These cause the referencing column(s) in the referencing row(s) to be set to nulls or their default values, respectively, when the
referenced row is deleted. Note that these do not excuse you from observing any constraints. For example, if an action specifies SET DEFAULT but the
default value would not satisfy the foreign key constraint, the operation will fail. Analogous to ON DELETE there is also ON UPDATE which is invoked
when a referenced column is changed (updated). The possible actions are the same. In this case, CASCADE means that the updated values of the referenced
column(s) should be copied into the referencing row(s). Normally, a referencing row need not satisfy the foreign key constraint if any of its referencing
columns are null. If MATCH FULL is added to the foreign key declaration, a referencing row escapes satisfying the constraint only if all its referencing
columns are null (so a mix of null and non-null values is guaranteed to fail a MATCH FULL constraint). If you don't want referencing rows to be able to
avoid satisfying the foreign key constraint, declare the referencing column(s) as NOT NULL. A foreign key must reference columns that either are a primary
key or form a unique constraint. This means that the referenced columns always have an index (the one underlying the primary key or unique constraint); so
checks on whether a referencing row has a match will be efficient. Since a DELETE of a row from the referenced table or an UPDATE of a referenced
column will require a scan of the referencing table for rows matching the old value, it is often a good idea to index the referencing columns too. Because this
is not always needed, and there are many choices available on how to index, declaration of a foreign key constraint does not automatically create an index on
the referencing columns.
Modifying Tables
You can:
• Add columns • Remove columns • Add constraints • Remove constraints
• Change default values • Change column data types • Rename columns • Rename tables
All these actions are performed using the ALTER TABLE command.
Adding a Column
To add a column, use a command like:
ALTER TABLE products ADD COLUMN description text;
The new column is initially filled with whatever default value is given (null if you don't specify a DEFAULT clause).
You can also define constraints on the column at the same time, using the usual syntax:
ALTER TABLE products ADD COLUMN description text CHECK (description <> '');
In fact all the options that can be applied to a column description in CREATE TABLE can be used here. Keep in mind however that the default value must
satisfy the given constraints, or the ADD will fail. Alternatively, you can add constraints later (see below) after you've filled in the new column correctly.
Removing a Column
To remove a column, use a command like:
ALTER TABLE products DROP COLUMN description;
Whatever data was in the column disappears. Table constraints involving the column are dropped, too. However, if the column is referenced by a foreign key
constraint of another table, PostgreSQL will not silently drop that constraint. You can authorize dropping everything that depends on the column by adding
CASCADE:
ALTER TABLE products DROP COLUMN description CASCADE;
Adding a Constraint
Vishnuvardhan Mannava 15
Basic SQL Queries
To add a constraint, the table constraint syntax is used. For example:
ALTER TABLE products ADD CHECK (name <> '');
ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no);
ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups;
To add a not-null constraint, which cannot be written as a table constraint, use this syntax:
ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;
The constraint will be checked immediately, so the table data must satisfy the constraint before it can be added.
Removing a Constraint
To remove a constraint you need to know its name. If you gave it a name then that's easy. Otherwise the system assigned a generated name, which you need
to find out. The psql command \d tablename can be helpful here; other interfaces might also provide a way to inspect table details. Then the command
is:
ALTER TABLE products DROP CONSTRAINT some_name;
(If you are dealing with a generated constraint name like $2, don't forget that you'll need to doublequote it to make it a valid identifier.)
As with dropping a column, you need to add CASCADE if you want to drop a constraint that something else depends on. An example is that a foreign key
constraint depends on a unique or primary key constraint on the referenced column(s).
This works the same for all constraint types except not-null constraints. To drop a not null constraint use:
ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
(Recall that not-null constraints do not have names.)
Changing a Column's Default Value
To set a new default for a column, use a command like:
ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
Note that this doesn't affect any existing rows in the table, it just changes the default for future INSERT commands.
To remove any default value, use:
ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
This is effectively the same as setting the default to null. As a consequence, it is not an error to drop a default where one hadn't been defined, because the
default is implicitly the null value.
Changing a Column's Data Type
To convert a column to a different data type, use a command like:
ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
This will succeed only if each existing entry in the column can be converted to the new type by an implicit cast. If a more complex conversion is needed,
you can add a USING clause that specifies how to compute the new values from the old.
PostgreSQL will attempt to convert the column's default value (if any) to the new type, as well as any constraints that involve the column. But these
conversions might fail, or might produce surprising results. It's often best to drop any constraints on the column before altering its type, and then add back
suitably modified constraints afterwards.
Renaming a Column
To rename a column:
ALTER TABLE products RENAME COLUMN product_no TO product_number;
Renaming a Table
To rename a table:
ALTER TABLE products RENAME TO items;
Inheritance
Inheritance is a concept from object-oriented databases. It opens up interesting new possibilities of database design.
Let's create two tables: A table cities and a table capitals. Naturally, capitals are also cities, so you want some way to show the capitals implicitly
when you list all cities. If you're really clever you might invent some scheme like this:
CREATE TABLE capitals ( CREATE TABLE non_capitals (
name text, name text,
population real, population real,
altitude int, -- (in ft) altitude int -- (in ft)
state char(2) );
);
CREATE VIEW cities AS
SELECT name, population, altitude FROM capitals
UNION
SELECT name, population, altitude FROM non_capitals;
This works OK as far as querying goes, but it gets ugly when you need to update several rows, for one thing. A better solution is this:
CREATE TABLE cities ( CREATE TABLE capitals (
name text, state char(2)
population real, ) INHERITS (cities);
altitude int -- (in ft)
);
In this case, a row of capitals inherits all columns (name, population, and altitude) from its parent, cities. The type of the column name is
text, a native PostgreSQL type for variable length character strings. State capitals have an extra column, state, that shows their state. In PostgreSQL, a
table can inherit from zero or more other tables.
Views
Suppose the combined listing of weather records and city location is of particular interest to your application, but you do not want to type the query each
time you need it.You can create a view over the query, which gives a name to the query that you can refer to like an odinary table:
CREATE VIEW myview AS
SELECT city, temp_lo, temp_hi, prcp, date, location
FROM weather, cities
WHERE city = name;
SELECT * FROM myview;
Making liberal use of views is a key aspect of good SQL database design. Views allow you to encapsulate the details of the structure of your tables, which
might change as your application evolves, behind consistent interfaces. Views can be used in almost any place a real table can be used. Building views upon
other views is not uncommon.
Vishnuvardhan Mannava 16

You might also like