��SQL: Structured Query Language�(SQL Basics) �
Professor Sharad Mehrotra
UC Irvine
SQL in Different Roles
Covered earlier
Next topic
Later
Covered in CS 122b
Covered in CS 223
Sample Schema
Patients(name, age) -- patients who currently have some disease
RecoveredPatients(name, age) -- patients who have recovered from the disease they had. They may still have other diseases in which case they will also be part of the Patients table as well.
Diagnosis(pname, disease, diagnosis_date) -- the diagnosis made about patients on a given date.
ToDiagnose(disease, test) -- tests used to diagnose the disease
Outcomes(pname, test, result, test_date) -- the result of the test when conducted on the patient pid on the given date.
3
SQL as a Query Language
4
4
select A1, A2, …, An� from R1, R2, …, Rm
where <conditions>;
Examples:
select pname
from Diagnosis
where disease = ‘Flu’;
select test
from ToDiagnose
where disease = ‘Flu’
SQL vs Relational Algebra
5
5
Difference:
SELECT A1, A2, …, An� FROM R1, R2, …, Rm
WHERE <conditions>;
ΠA1,…,An (σ cond (R1 × R2 × … Rm))
~
=
“Select” clause
SELECT *
FROM Patients
WHERE age > 18
Will return <name, age> of all the patients over 18 years of age
6
6
Eliminate duplicates
Select pname
From Diagnosis;
Select distinct pname
From Diagnosis;
7
7
The select Clause (Cont.)
select *� from Diagnosis
select "Mary"
select ‘Mary’ as FOO
select "A"� from Diagnosis
©Silberschatz, Korth and Sudarshan
3.8
Database System Concepts - 6th Edition
The select Clause (Cont.)
select name, age+3� from Patients
would return a relation that is the same as the Patients relation, except that the value of the attribute age replaced by age+3
select name, age+3 as future_age�
©Silberschatz, Korth and Sudarshan
3.9
Database System Concepts - 6th Edition
“FROM” clause
SELECT distinct P1.name
FROM Patients as P1, Patients as P2
WHERE P1.age < P2.age
10
10
“WHERE” clause
SELECT pname
FROM Outcomes
WHERE test = “A” AND result = true;
String patterns:
11
11
Conditions in a “WHERE” clause
SELECT Patients.name
FROM Patients, Diagnosis
WHERE Patients.name = Diagnosis.pname;
12
12
“WHERE” Clause Predicates
select * from Outcomes
where test_date between '2020-01-01' and '2021-01-01';
select Patients.name, RecoveredPatients.name
from Patients, RecoveredPatients
where (Patients.name, Patients.age) = (RecoveredPatients.name, RecoveredPatients.age);
13
Ordering output tuples
select *
from Outcomes
order by result, test, pname desc;
Order the tuples by
14
14
Set Operations
(select name from Patients)
union
(select name from RecoveredPatients);
(select name from Patients)
intersect
(select name from RecoveredPatients);
(select name from Patients)
except
(select name from RecoveredPatients);
15
15
Example Query with Set Operations
16
16
R = {1,2, 4 } S = {1,3} T {1,4,6} {1,4}
Query: “R ∩ (S ∪ T)”
select * from R intersect
((select * from S) union (select * from T))
R
S
T
Could we write it as a SPJ Query?
17
17
R = {1,2, 4 } S = {1,3} T {1,4,6} {1,4}
SELECT distinct R.A
FROM R, S, T
WHERE R.A=S.A OR R.A=T.A;
R
S
T
Unintuitive SQL query
18
18
SELECT R.A
FROM R, S, T
WHERE R.A=S.A OR R.A=T.A;
E.g., R= {1,2, 4} S = {1,2,4} answer we want {1,2,4}, answer we get is empty
R
S
T
Conserving Duplicates
19
19
(select name from Patients)
union all
(select name from RecoveredPatients);
Set Operations (Cont.)
20
Aggregations
select min(age), max(age), avg(age) from Patients;
21
21
Aggregations (cont)
SELECT Count(*) FROM Patients;
SELECT Count(name) FROM Patients;
22
22
Duplication in aggregations
Select count(test)
From Outcomes
Is this correct?
23
23
'Al','G','1','2020-02-16'
'Alex','A','1','2020-01-03'
'Alex','G','1','2020-01-03'
'Barbara','G','0','2020-02-10'
'Bob','C','1','2021-02-01'
'Jane','B','1','2021-01-01'
'Jane','C','0','2021-01-01'
'Jane','F','0','2021-01-01'
'Mary','A','1','2020-01-01'
'Mary','A','1','2021-01-01'
'Mary','B','0','2021-01-01'
'Mary','D','1','2021-01-01'
'Mehdi',' F','1','2021-01-02'
'Mehdi','E','0','2021-01-02'
'Mehdi','E','1','2021-01-02'
Duplication in aggregations
select count(distinct test)
from Outcomes;
24
24
Group By clause
select disease,count(pname)
from Diagnosis
group by disease;
25
25
Group By clause
select pname, count(*)
from Outcomes
group by pname;
26
26
Group By clause (cont)*
select Outcomes.pname, count(*), age
from Outcomes, Patients
group by pname;
27
27
14:04:30 select Outcomes.pname, count(*), age from Outcomes, Patients group by pname LIMIT 0, 1000 Error Code: 1055. Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'patientdb.Patients.age' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 0.00032 sec
Group By clause (cont)
SELECT name
FROM Patients
GROUP BY name;
SELECT DISTINCT name
FROM Patients;�
28
28
Having Clause
select pname, count(*)
from Outcomes
group by pname
having count(*) > 3
29
29
A general SQL query
30
30
List all tests for which there are at least 2 patients have had a positive and a negative result
SELECT O1.test, count(*)
FROM Outcomes AS O1, Outcomes AS O2
WHERE O1.test = O2.test AND
O1.result = true AND
O2.result = false AND
O1.pname = O2.pname
GROUP BY O1.test
HAVING count(*) > 1
ORDER BY by O1.test;
A general SQL query (cont)
31
31
SELECT O1.test, count(*) ---------(5)
FROM Outcomes AS O1, Outcomes AS O2 -- (1)
WHERE O1.test = O2.test AND ----- ---- (2)
O1.result = true AND
O2.result = false AND
O1.pname = O2.pname
GROUP BY O1.test ---------(3)
HAVING count(*) > 1 ----------(4)
ORDER BY by O1.test; ----------(6)
Execution steps:
Step 1: tuples are formed (Cartesian product)
Step 2: tuples satisfying the conditions are chosen (selection)
Step 3: groups are formed (grouping)
Step 4: groups are eliminated using “Having” (selection applied on groups)
Step 5: the aggregates are computed for the select line, flattening the groups
Step 6: the output tuples are ordered and printed out.
Nulls in SQL
32
NULL Values in SQL
33
Using NULL Values
34
Truth Table for Three-valued Logic
One suggested way to remember the rules (though they are very intuitive, IMO):
35
TRUE
TRUE
TRUE
TRUE
FALSE
x
y
x AND y
x OR y
NOT x
TRUE
UNKNOWN
UNKNOWN
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
UNKNOWN
TRUE
UNKNOWN
TRUE
UNKNOWN
UNKNOWN
UNKNOWN
UNKNOWN
UNKNOWN
UNKNOWN
UNKNOWN
FALSE
False
UNKNOWN
UNKNOWN
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
UNKNOWN
FALSE
UNKNOWN
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
NULL is Not a SQL Constant
(I.e., NULL is not a value, it’s the state of a value)
36
NULL Examples
SELECT *
FROM Patients
WHERE age IS NULL;
37
Patients Table
NULL Examples (cont.)
SELECT *
FROM Patients
WHERE age > 40;
38
(Only tuples for which condition evaluates to TRUE become part of answer!)
!!!
SELECT *
FROM Patients
WHERE age <= 40
OR age >= 40;
Null Values and Aggregates
39
select avg (age )
from Patients
SQL: Subqueries, Joins, �Modifications.
40
Nested Subqueries
�as follows:
[B] <operation> (subquery)
©Silberschatz, Korth and Sudarshan
3.41
Database System Concepts - 6th Edition
Subqueries in WHERE Clause
Example: Who has same disease as Mehdi
42
SELECT pname
FROM Diagnosis
WHERE disease IN (
SELECT disease
FROM Diagnosis
WHERE pname = 'Mehdi'
);
SELECT D1.pname
FROM Diagnosis AS D1, Diagnosis AS D2
WHERE D1.disease = D2.disease
AND D2.pname = 'Mehdi';
Semantics:
Conditions involving Relations
43
Definition of “all” Clause
0
5
6
(5 < all
) = false
6
10
4
) = true
5
4
6
(5 ≠ all
) = true (since 5 ≠ 4 and 5 ≠ 6)
(5 < all
) = false
(5 = all
(≠ all) ≡ not in
However, (= all) ≡ in
©Silberschatz, Korth and Sudarshan
3.44
Database System Concepts - 6th Edition
Example 1: Find the patients with the highest age.
45
SELECT name
FROM Patients
WHERE age >= ALL (select age from Patients);
SELECT name
FROM Patients
WHERE age >= ALL (select age from Patients where age is not null);
Equivalent query:
SELECT name
FROM Patients where age = (SELECT max(age) FROM Patients);
Will not work if age could be null
modified query to take care of null values
Definition of “some” Clause
0
5
6
(5 < some
) = true
0
5
0
) = false
5
0
5
(5 ≠ some
) = true (since 0 ≠ 5)
(read: 5 < some tuple in the relation)
(5 < some
) = true
(5 = some
(= some) ≡ in
However, (≠ some) ≡ not in
©Silberschatz, Korth and Sudarshan
3.46
Database System Concepts - 6th Edition
Example 2
47
SELECT name FROM Patients
WHERE age > SOME
(SELECT age FROM Patients, Diagnosis
WHERE Patients.name = Diagnosis.pname AND Diagnosis.disease = 'Mono');
Testing Empty Relations
FROM Patients P1
WHERE exists
(SELECT name
FROM RecoveredPatients P2
WHERE P1.age > P2.age);
48
Patients
RecoveredPatients
Resultset
Testing Empty Relations (cont)
49
Subqueries producing one value
50
select name
from Patients
where patients.name =
(select pname
from Diagnosis
where disease =”Mono”);
Subqueries in the From Clause
©Silberschatz, Korth and Sudarshan
3.51
Database System Concepts - 6th Edition
Example Query
select disease, avg(P1.age)�from Diagnosis, Patients P1
where P1.name =Diagnosis.pname� Group by disease � Having avg(P1.age) > 50;
We could write the same query using a nested subquery in the from clause
©Silberschatz, Korth and Sudarshan
3.52
Database System Concepts - 6th Edition
Subqueries in the Form Clause
select A.disease, A.avg_age
from (select disease, avg (age) as avg_age
from Diagnosis D1, Patients P1
where P1.name =D1.pname
Group by disease) as A
where A.avg_age > 50;
©Silberschatz, Korth and Sudarshan
3.53
Database System Concepts - 6th Edition
With Clause
Find all Patients with the maximum age �� with max_age(age) as
(select max(age)
from Patients)
select Patients.name
from Patients, max_age
where Patients.age = max_age.age;
©Silberschatz, Korth and Sudarshan
3.54
Database System Concepts - 6th Edition
Complex Queries using With Clause
with
disease_avg (disease, age) as
(select d1.disease, avg(age)
from Patients, Diagnosis d1
where d1.pname = Patients.name
group by disease),
avg_age(age) as
(select avg(age)
from Patients)
select distinct disease_avg.disease
from avg_age, disease_avg
where disease_avg.age> avg_age.age;
©Silberschatz, Korth and Sudarshan
3.55
Database System Concepts - 6th Edition
Subqueries in SELECT Clause
List people and number of diseases they have
select distinct pname, (select count(*)
from Diagnosis as D1
where D1.pname =Diagnosis.pname )
from Diagnosis
;; Runtime error if subquery returns more than one result tuple
Alternate query
select pname, count(*) from Diagnosis group by pname
©Silberschatz, Korth and Sudarshan
3.56
Database System Concepts - 6th Edition
57
Joins
58
Cross Join
SELECT * from Diagnosis CROSS JOIN Patients;
SELECT Diagnosis.disease, Patients.age
FROM Patients JOIN Diagnosis ON Patients.name = Diagnosis.pname;
Natural Joins
select * from Outcomes NATURAL JOIN ToDiagnose;
Equivalent to:
SELECT Outcomes.test, Outcomes.pname, Outcomes.result, Outcomes.test_Date,ToDiagnose.disease
FROM Outcomes CROSS JOIN ToDiagnose ON Outcomes.test =ToDiagnose.test;
59
Natural Left/Right Outer Joins
Outcomes o NATURAL LEFT JOIN ToDiagnose td ;
Pad NULL values to dangling tuples of ToDiagnose.
60
Outcomes o NATURAL RIGHT OUTER JOIN ToDiagnose td ;
Pad NULL values to dangling tuples of Outcomes.
Natural Full Outer Joins
SELECT *
FROM ToDiagnose NATURAL FULL OUTER JOIN Outcomes;
Pad NULL values to both relations. /* NOT SUPPORTED in MYSQL */
instead use
SELECT * FROM ToDiagnose NATURAL LEFT OUTER JOIN Outcomes union
SELECT * FROM ToDiagnose NATURAL RIGHT OUTER JOIN Outcomes;
61
Outer Join on different attributes
student FULL OUTER JOIN dept
ON student.dno = dept.dept#; → different attribute names
62
Join Summary
Again: Different vendors might have different implementations.
63
Test your SQL knowledge …which of these are equivalent queries!
(select name from Patients)
except
(select name from RecoveredPatients);
select P.name
from Patients as P LEFT JOIN RecoveredPatients as R on P.name = R.name
where R.name is NULL
select P.name
from Patients as P NATURAL LEFT JOIN RecoveredPatients as R
where R.name is NULL
select P.name
from Patients as P
where P.name not in (select name from RecoveredPatients)
64
Test your SQL knowledge …which of these are equivalent queries!
What would your answer be under the following conditions:
65
Database Modifications
66
Insert Delete Update
Delete
67
DELETE FROM relation [WHERE conditions];
DELETE
FROM Patients
WHERE name in (select name from RecoveredPatients);
DELETE
FROM Patients; → all tuples will be deleted
Insertion of a tuple
68
INSERT INTO R(A1,…,An) VALUES (v1,…,vn)
INSERT INTO `Outcomes`(pname,test, test_date, result) VALUES ('Mary','H','2022-09-01', 0);
INSERT INTO `Outcomes` VALUES ('Mary','H',0,'2022-09-01');
INSERT INTO Patients(name)
VALUES (‘Daniel’);
Insertion of a query’s result
INSERT INTO relation (subquery);
INSERT INTO Patients
( SELECT *
FROM RecoveredPatients
WHERE name not in (select name from Patients)
);
.
69
Delete (cont)
70
DELETE
FROM Patients P1
WHERE EXISTS
(SELECT pname
FROM Diagnosis D1
WHERE P1.name = D1.pname AND D1.disease='Strep');
Update
71
UPDATE relation SET assignments WHERE condition
UPDATE Patients
SET age = 36
WHERE age = 35;
UPDATE PATIENTS
SET name = ‘Mary’, age = age +5
WHERE name = ‘Mary’;