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

Databases I - 04 SQL-DQL,other

The document provides an overview of SQL queries, specifically focusing on Data Query Language (DQL) examples and syntax. It includes examples of queries to retrieve student grades, course titles, and ECTS points, as well as explanations of SQL commands like SELECT, FROM, and WHERE. Additionally, it covers comparison and boolean operators, set operations, and how to structure SQL queries effectively.

Uploaded by

kgztjmqsss
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Databases I - 04 SQL-DQL,other

The document provides an overview of SQL queries, specifically focusing on Data Query Language (DQL) examples and syntax. It includes examples of queries to retrieve student grades, course titles, and ECTS points, as well as explanations of SQL commands like SELECT, FROM, and WHERE. Additionally, it covers comparison and boolean operators, set operations, and how to structure SQL queries effectively.

Uploaded by

kgztjmqsss
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

09/05/2025

Queries
SQL - DQL

1
09/05/2025

Queries
Examples:
• We want to know which students have achieved grades higher than 8.
• We would like to see the title of courses and the ECTS points of courses with more than 5 ECTS
points.
• We would like to see a list of the names of students born after 2007 who have achieved grades
higher than 7 in courses with more than 5 ECTS points.

191

Demand result
• The result of the query is a new table.
• Example: we want to know which students have achieved grades higher than 8.
Student
id_s name last_name enrolment_nr date_of_birth email height enrolment_costs gender tshirt_no
1 David Novak E9320376041 12.12.2008 david@feri.si 180,3 12,33 M L
2 Maja Krajnc E3107410974 15.03.2008 maja@epf.si NULL 15,78 Ž M
3 Ales Novak E1234464687 NULL ales@feri.si 175,3 12,33 M M
4 Maja Malič E2137410974 15.05.2009 maja@pf.si 165,8 16,88 Ž S

Enrolment
Students_with_grades_above_8
year_of_enr
id_e grade FK_Student FK_Course year_of_enr
olment id_e grade name last_name FK_Course
olment
1 8 2026/2027 1 1
3 9 2026/2027 Maja Krajnc 4
2 7 2026/2027 1 2
4 9 2026/2027 Maja Krajnc 5
3 9 2026/2027 2 4
6 10 2026/2027 Ales Novak 3
4 9 2026/2027 2 5
5 NULL 2026/2027 3 1
Students_with_grades_above_8
6 10 2026/2027 3 3
id_s name last_name
7 6 2025/2026 4 6
8 8 2025/2026 4 7 2 Maja Krajnc
192
3 Ales Novak

2
09/05/2025

Basic demand
The query will result in a new table.
The basic form of demand:
SELECT A1, A2, ... An  list of columns (attributes) to be displayed
FROM T1, T2, ..., Tm  list of tables from which to extract data
WHERE conditions  conditions that specify what data we want to
see

193

Comparison and Boolean operators in MySQL


 They are mainly used to compare numeric and time data types.
Comparative functions and operators Logical operators
name Description name Description
> Larger
AND, && Logical and
>= Greater than or equal to

< Smaller NOT, ! Negative values


<>, != Not the same OR, || Logical or
<= Less or equal

= Same  The AND operator displays a line


BETWEEN ... AND ... Between two values if all conditions separated by
GREATEST() The biggest AND are valid (true).
IS Is within the BOOLEAN type value  The OR operator displays a line if
IS NOT No value within BOOLEAN type any condition separated by OR is
IS NOT NULL no NULL value true.
IS NULL is a NULL value  The NOT operator displays a line
LIKE contained in if the condition is not valid (not
NOT BETWEEN ... AND ... Not between two values true). 194

3
09/05/2025

Constructs for operations on sets


• Operations above the crowds
• UNION - Union 
• INTERSECT - press 
• EXCEPT - difference \
• Additional operations
• IN - whether an element belongs to a set
• ANY - whether there are any elements in the set
• ALL - comparison of values with elements in a given set
• EXISTS - check if the set is not empty

195

SELECT
• SELECT A1, A2, ... An
• With A1, A2 ..., we define the names of the columns we want to
have extracted from the tables. The order of the output will be
the same as the order of the SELECT statement.
• Use * to list all columns from the selected tables.
SELECT * FROM table1
SELECT table1.*, attribute_from_table2 FROM table1, table2 WHERE ...
• Each column can be renamed with an AS and a new column
name (e.g. AS name 'Student name').
SELECT attribute1 AS 'New name' FROM table1

196

4
09/05/2025

SELECT
• SELECT A1, A2, ... An
• The word DISTINCT allows duplicate lines to be deleted. It is used
immediately after the SELECT command. If multiple columns are defined
at the same time, DBMS searches for all different combinations of values
of the selected columns.
SELECT DISTINCT attribute1, attribute2 FROM table1
• It can also contain aggregate functions (MIN, MAX, SUM, AVG, COUNT)
SELECT attribute 1, SUM(attribute2) AS 'total'
FROM table1
WHERE condition
GROUP BY table1.attribute3;

197

FROM
• FROM T1, T2, ..., Tm
• T1, T2,... is the list of tables from which the data is extracted.
• You can use a shorter name (e.g. Table T) and then use the abbreviation
throughout the sentence. This is particularly useful when we have long
table names, or when we are listing pairs from the same table.
• JOIN operators can be used to join tables in a FROM section.
• It can also contain a nested statement (SELECT ... ) AS name.

198

5
09/05/2025

WHERE
• WHERE conditions
• Conditions are defined using a column, where we check the condition,
then include comparison functions or operators and a value to define the
demand.
• We can use comparison functions and operators
• >, >=, <, <>, !=, <=, =
• BETWEEN ... AND ..., GREATEST(), IS, IS NOT, IS NOT NULL, IS NULL,
LIKE, NOT BETWEEN ... AND ..., NOT LIKE
SELECT * FROM table
WHERE attribute > value1
AND attribute2 BETWEEN value2 AND value3;

199

WHERE
• WHERE conditions
• Multiple conditions can be combined with AND; OR or NOT
• In case of multiple conditions, the use of brackets is recommended.
SELECT * FROM table
WHERE ID_table1 = value1
AND (ID_table1 = value2
OR table_id1 = value3);

200

6
09/05/2025

WHERE
• WHERE conditions
• Allows nested statements to be used with operations on sets.
• UNION, INTERSECT, EXCEPT
SELECT *
FROM table
UNION
SELECT *
FROM table2;
• IN, ANY, ALL, EXISTS
SELECT *
FROM table
WHERE attribute IN
(SELECT attribute1
FROM table2);

201

SQL gone wrong

202

7
09/05/2025

Example

Student
enrolment_expens
id_s name last_name enrolment_nr date_of_birth email height gender tshirt_no
e
1 David Novak E9320376041 12.12.2008 david@feri.si 180,3 12,33 M L
2 Maja Krajnc E3107410974 15.03.2008 maja@epf.si NULL 15,78 Ž M
3 Ales Novak E1234464687 NULL ales@feri.si 175,3 12,33 M M
4 Maja Malič E2137410974 15.05.2009 maja@pf.si 165,8 16,88 Ž S
Enrolment
Course
year_of_enr
id_c course_code course_title ects_points id_e grade FK_Student FK_Course
olment
1 62V108 Databases I 5
1 8 2026/2027 1 1
2 61V013 Computer networks 5
2 7 2026/2027 1 2
3 62V014 Information systems architectures 5 3 9 2026/2027 2 4
4 V035 Quality management 5 4 9 2026/2027 2 5
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1
6 U0003 Roman law 8 6 10 2026/2027 3 3 203
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6
8 8 2025/2026 4 7

SELECT, *, FROM
• You can use * to output all columns in the table.

• We want to print all the data that are in the table enrolment.
SELECT *
FROM enrolment; Result
year_of_enr
id_e grade FK_Student FK_Course
olment
1 8 2026/2027 1 1
2 7 2026/2027 1 2
3 9 2026/2027 2 4
Enrolment
4 9 2026/2027 2 5
year_of_enr
id_e grade FK_Student FK_Course 5 NULL 2026/2027 3 1
olment
6 10 2026/2027 3 3
1 8 2026/2027 1 1
7 6 2025/2026 4 6
2 7 2026/2027 1 2
8 8 2025/2026 4 7
3 9 2026/2027 2 4
4 9 2026/2027 2 5
5 NULL 2026/2027 3 1
6 10 2026/2027 3 3
7 6 2025/2026 4 6
8 8 2025/2026 4 7
204

8
09/05/2025

SELECT, AS, FROM


• We can extract only certain columns (column names are listed
in SELECT) from the table and rename the columns with AS.
• We want a printout of all student IDs and their grades.
SELECT FK_student AS 'Student No.', year_of_enrolment,
grade
FROM enrolment;

Enrolment
Enrolment
year_of_enr
year_of_enr Student no. grade
id_e grade FK_Student FK_Course olment
olment
1 2026/2027 8
1 8 2026/2027 1 1
1 2026/2027 7
2 7 2026/2027 1 2
2 2026/2027 9
3 9 2026/2027 2 4
2 2026/2027 9
4 9 2026/2027 2 5
3 2026/2027 NULL
5 NULL 2026/2027 3 1
3 2026/2027 10
6 10 2026/2027 3 3
4 2025/2026 6
7 6 2025/2026 4 6
4 2025/2026 8
8 8 2025/2026 4 7 205

SELECT, FROM, WHERE


• In WHERE, we specify a condition and the result prints every row for which that
condition applies.

• We want to see a list of courses with more than 5 ECTS points.


SELECT *
Result
FROM course id_c course_code course_title ects_points
5 V274 Performance marketing 6
WHERE ects_points > 5; 6 U0003 Roman law 8
7 U005 Substantive criminal law 8

Course
id_c course_code course_title ects_points
1 62V108 Databases I 5
2 61V013 Computer networks 5
Information systems
3 62V014 5
architectures
4 V035 Quality management 5
5 V274 Performance marketing 6
6 U0003 Roman law 8 206
7 U005 Substantive criminal law 8

9
09/05/2025

Comparison operators >, >=, <, <>, !=, <=, =


• Comparison operators compare two values against each other.
• We would like to see the title of courses and the ECTS points of courses
with more than 5 ECTS points.
SELECT course_title, point_ECTS Result
FROM course course_title ects_points
Performance marketing 6
WHERE ects_points > 5; Roman law 8
Substantive criminal law 8

Course
id_c course_code course_title ects_points
1 62V108 Databases I 5
2 61V013 Computer networks 5
Information systems
3 62V014 5
architectures
4 V035 Quality management 5
5 V274 Performance marketing 6
6 U0003 Roman law 8 207
7 U005 Substantive criminal law 8

Course
id_c course_code course_title ects_points
1 62V108 Databases I 5

Comparison operators >, 2


3
61V013
62V014
Computer networks
Information systems
architectures
5
5

>=, <, <>, !=, <=, = 4


5
V035
V274
Quality management
Performance marketing
5
6
6 U0003 Roman law 8
7 U005 Substantive criminal law 8
SELECT course_title, point_ECTS
SELECT course_title, point_ECTS
FROM course Result Result
course_title ects_points FROM course course_title ects_points
WHERE ects_points > 6; Roman law 8 Databases I 5
Substantive criminal law 8 WHERE ects_points <> 6; Computer networks 5
Information systems architectures 5
#or != Quality management 5
SELECT course_title, point_ECTS Roman law 8
Substantive criminal law 8
FROM course Result
course_title ects_points SELECT course_title, point_ECTS
WHERE ects_points >= 6; Performance marketing 6 Result
Roman law 8 FROM course course_title ects_points
Substantive criminal law 8 Databases I 5
WHERE ects_points <= 6; Computer networks 5
SELECT course_title, point_ECTS Information systems architectures
Quality management
5
5

FROM course Result


Performance marketing 6

course_title ects_points SELECT course_title, point_ECTS


WHERE ects_points < 6; Databases I 5 Result
Computer networks 5 FROM course course_title ects_points
Information systems architectures 5 Performance marketing 6
Quality management 5 WHERE ects_points = 6;
208

10
09/05/2025

Comparative operator BETWEEN ... AND ... / NOT BETWEEN ... AND ...

• WHERE attribute BETWEEN value1 AND value2


• Otherwise the same as >= and <=, so the first number in the comparison must be
smaller than the second.
• For example, if we have 5 BETWEEN 10 AND 1, it is not true, but if 5 BETWEEN 1 and
10, it is true.
• You can also use NOT BETWEEN value1 AND value2 (< OR >).
SELECT name, last_name, date_of_birth
FROM student
WHERE date_of_birth BETWEEN '2008-03-15' AND '2009-01-01';
student
last_na enrolment_ date_of_birt
id_s name
me nr h
E932037604 Result
1 David Novak 12.12.2008 name last_name date_of_birth
1
E310741097 David Novak 12.12.2008
2 Maja Krajnc 15.03.2008
4 Maja Krajnc 15.03.2008
E123446468
3 Ales Novak NULL
7
E213741097 209
4 Maja Malič 15.05.2009
4

Comparison operator IS / IS NOT & GREATEST()


• WHERE attribute IS TRUE / FALSE
• It works with the BOOLEAN value because it checks if the
sentence is true or not.
• IS NOT true / false can also be used
student
SELECT name, last_name, gender Result last_na enrolment date_of_bi gende
id_s name
FROM student name last_name gender me _nr rth r
David Novak 1 E93203760
WHERE spol IS true; Ales Novak 1
1 David Novak
41
12.12.2008 1
E31074109
2 Maja Krajnc 15.03.2008 0
74
SELECT name, last_name, gender E12344646
Result 3 Ales Novak NULL 1
87
FROM student name last_name gender E21374109
4 Maja Malič 15.05.2009 0
WHERE spol IS NOT true; / IS false; Maja Krajnc 0 74
Maja Malič 0

• GREATEST(value1,value2)
• It chooses the highest of the given values. Result
SELECT GREATEST(5, 6, 7); GREATEST
7
210

11
09/05/2025

Comparison operator IS NULL / IS NOT NULL


• WHERE attribute IS NULL
• We check where in the column there is an empty or unknown row (NULL).
• The IS NOT NULL attribute can also be used

SELECT name, last_name, date_of_birth Result


FROM student name last_name date_of_birth
Ales Novak NULL
WHERE date_of_birth IS NULL;

Result
SELECT name, last_name, date_of_birth name last_name date_of_birth
FROM student David Novak 12.12.2008
WHERE date_of_birth IS NOT NULL; Maja Krajnc 15.03.2008
Maja Malič 15.05.2009

student
id_s name last_name enrolment_nr date_of_birth
1 David Novak E9320376041 12.12.2008
2 Maja Krajnc E3107410974 15.03.2008
3 Ales Novak E1234464687 NULL 211
4 Maja Malič E2137410974 15.05.2009

Comparative operator LIKE / NOT LIKE


• WHERE attribute LIKE value1
• We can include % and _, which are wildcards for arbitrary characters. They can be used
multiple times in one string.
• % represents the substitution of several arbitrary characters, _ represents exactly one
arbitrary character.
• Examples: %A%, %A, A%, _A, A_, __A, _A_, %A_,...
• You can also use NOT LIKE value1

SELECT grade, year_of_enrolment


FROM enrolment
WHERE year_of_enrolment LIKE '%25/20%'; / LIKE '%25/2026' / LIKE '_025/%'
Enrolment
year_of_enr
id_e grade FK_Student FK_Course
olment
1 8 2026/2027 1 1 Result
2 7 2026/2027 1 2 grade year_of_enrolment
3 9 2026/2027 2 4 6 2025/2026
4 9 2026/2027 2 5 8 2025/2026
5 NULL 2026/2027 3 1
6 10 2026/2027 3 3 212
7 6 2025/2026 4 6
8 8 2025/2026 4 7

12
09/05/2025

Logical operator AND


• The WHERE clauses can be joined together using the AND logical operator.

• We want to extract students born before 2009 and named Maja.


SELECT *
FROM student
WHERE date_of_birth <= '2008-12-31' Result
last_nam
AND name = 'Maja'; id_s name
e
enrolment_nr date_of_birth
4 Maja Krajnc E3107410974 15.03.2008

student
id_s name last_name enrolment_nr date_of_birth
1 David Novak E9320376041 12.12.2008
2 Maja Krajnc E3107410974 15.03.2008
3 Ales Novak E1234464687 NULL 213
4 Maja Malič E2137410974 15.05.2009

Logical OR operator
• Conditions within a WHERE can also be joined together using the logical
OR operator, provided that both conditions (before and after the OR) can be
valid.

• We would like to see a list of students born after 2008 with the name Maja,
as well as students with the last_name Novak. Result
SELECT * id_s name
last_nam
enrolment_nr date_of_birth
e
FROM student 1 David Novak E9320376041 12.12.2008
3 Ales Novak E1234464687 NULL
WHERE date_of_birth > '2008-12-31' 4 Maja Malič E2137410974 15.05.2009
AND name = 'Maja'
OR last_name = 'Novak';
student
id_s name last_name enrolment_nr date_of_birth
1 David Novak E9320376041 12.12.2008
2 Maja Krajnc E3107410974 15.03.2008
3 Ales Novak E1234464687 NULL 214
4 Maja Malič E2137410974 15.05.2009

13
09/05/2025

Logical operator NOT


• Conditions within WHERE can also be joined together using the AND NOT
logical operator if the condition is not valid.

• We want a list of students who are spelled Novak and are not named David.
SELECT *
FROM student Result
last_nam
WHERE last_name = 'Novak' id_s name
e
enrolment_nr date_of_birth

AND NOT name = 'David'; 3 Ales Novak E1234464687 NULL

student
id_s name last_name enrolment_nr date_of_birth
1 David Novak E9320376041 12.12.2008
2 Maja Krajnc E3107410974 15.03.2008
3 Ales Novak E1234464687 NULL 215
4 Maja Malič E2137410974 15.05.2009

Extract from multiple tables without conditions


last_nam date_of_bi year_of_enro FK_stu FK_co
• When no conditions are added and two tables and all id_s name
e
Enrolment_st
rth
id_e grade
lment dent urse
1 David Novak E9320376041 12.12.2008 1 8 2026/2027 1
data are selected, the result is a Cartesian product. 2 Maja Krajnc E3107410974 15.03.2008 1 8 2026/2027 1
3 Ales Novak E1234464687 1 8 2026/2027 1

• Each row of the first table is assigned to each row of 4 Maja


1 David
Malič
Novak
E2137410974
E9320376041
15.05.2009
12.12.2008
1
2
8 2026/2027
7 2026/2027
1
1 2
the second table. 2 Maja
3 Ales
Krajnc
Novak
E3107410974
E1234464687
15.03.2008 2
2
7 2026/2027
7 2026/2027
1
1
2
2
4 Maja Malič E2137410974 15.05.2009 2 7 2026/2027 1 2
1 David Novak E9320376041 12.12.2008 3 9 2026/2027 2 4
2 Maja Krajnc E3107410974 15.03.2008 3 9 2026/2027 2 4
SELECT * SQL - DML 3 Ales
4 Maja
Novak
Malič
E1234464687
E2137410974
3
3
9 2026/2027
9 2026/2027
2
2
4
4
15.05.2009
FROM student, enrolment; 1 David
2 Maja
Novak
Krajnc
E9320376041
E3107410974
12.12.2008
15.03.2008
4
4
9 2026/2027
9 2026/2027
2
2
5
5
3 Ales Novak E1234464687 4 9 2026/2027 2 5
4 Maja Malič E2137410974 15.05.2009 4 9 2026/2027 2 5
1 David Novak E9320376041 12.12.2008 5 2026/2027 3
2 Maja Krajnc E3107410974 15.03.2008 5 2026/2027 3
3 Ales Novak E1234464687 5 2026/2027 3
student Enrolment 4 Maja Malič E2137410974 15.05.2009 5 2026/2027 3
year_of_enr 1 David Novak E9320376041 12.12.2008 6 10 2026/2027 3 3
last_na enrolment_ date_of_birt id_e grade FK_Student FK_Course 2 Maja Krajnc E3107410974 15.03.2008 6 10 2026/2027 3 3
id_s name olment
me nr h 3 Ales Novak E1234464687 6 10 2026/2027 3 3
E932037604 1 8 2026/2027 1 1 4 Maja Malič E2137410974 15.05.2009 6 10 2026/2027 3 3
1 David Novak 12.12.2008 2 7 2026/2027 1 2 1 David Novak E9320376041 12.12.2008 7 6 2025/2026 4 6
1
2 Maja Krajnc E3107410974 15.03.2008 7 6 2025/2026 4 6
E310741097 3 9 2026/2027 2 4 3 Ales Novak E1234464687 7 6 2025/2026 4 6
2 Maja Krajnc 15.03.2008 4 9 2026/2027 2 5
4 4 Maja Malič E2137410974 15.05.2009 7 6 2025/2026 4 6
E123446468 5 NULL 2026/2027 3 1 1 David Novak E9320376041 12.12.2008 8 8 2025/2026 4 7
3 Ales Novak NULL 2 Maja Krajnc E3107410974 15.03.2008 8 8 2025/2026 4 7
7 6 10 2026/2027 3 3 3 Ales Novak E1234464687 8 8 2025/2026 4 7
E213741097 7 6 2025/2026 4 6 4 Maja Malič E2137410974 15.05.2009 8 216
8 2025/2026 4 7
4 Maja Malič 15.05.2009
4 8 8 2025/2026 4 7

14
09/05/2025

Merging tables
• Tables T1 and T2 are linked by equating TK in T2, which is
equal to PK in T1.
• We would like to see a list of students' names and grades. name
Result
last_name grade
SELECT name, last_name, grade David
David
Novak
Novak
8
7
FROM student, enrolment Maja
Maja
Krajnc
Krajnc
9
9

WHERE student.id_s = enrolment.FK_student; Ales


Ales
Novak
Novak
NULL
10
Maja Malič 6
Maja Malič 8
This is one way to merge tables, we'll look at others later.
Enrolment
year_of_enr
id_e grade FK_Student FK_Course
olment
student 1 8 2026/2027 1 1
last_nam 2 7 2026/2027 1 2
id_s name enrolment_nr date_of_birth
e 3 9 2026/2027 2 4
1 David Novak E9320376041 12.12.2008 4 9 2026/2027 2 5
2 Maja Krajnc E3107410974 15.03.2008 5 NULL 2026/2027 3 1
3 Ales Novak E1234464687 NULL 6 10 2026/2027 3 3
4 Maja Malič E2137410974 15.05.2009 7 6 2025/2026 4 6 217
8 8 2025/2026 4 7

Merging tables
• We want to see a printout of students who have received a grade higher than 7.
SELECT *
FROM student, enrolment
WHERE student.id_s = enrolment.FK_student
AND grade > 7;
Result
year_of_enr
id_s name last_name enrolment_nr date_of_birth id_e grade id_c
olment
1 David Novak E9320376041 12.12.2008 1 8 2026/2027 1
2 Maja Krajnc E3107410974 15.03.2008 3 9 2026/2027 4
2 Maja Krajnc E3107410974 15.03.2008 4 9 2026/2027 5
3 Ales Novak E1234464687 NULL 6 10 2026/2027 3
4 Enrolment Maja Malič E2137410974 15.05.2009 8 8 2025/2026 7
year_of_enr
id_e grade FK_Student FK_Course
olment
1 8 2026/2027 1 1
student
2 7 2026/2027 1 2
last_nam
id_s name enrolment_nr date_of_birth 3 9 2026/2027 2 4
e
4 9 2026/2027 2 5
1 David Novak E9320376041 12.12.2008
5 NULL 2026/2027 3 1
2 Maja Krajnc E3107410974 15.03.2008
6 10 2026/2027 3 3
3 Ales Novak E1234464687 NULL
4 Maja Malič E2137410974 15.05.2009
7 6 2025/2026 4 6 218
8 8 2025/2026 4 7

15
09/05/2025

DISTINCT
• The word DISTINCT is used immediately after SELECT and selects only
DIFFERENT printouts in the result.
• We would like to see a list of the names of students born after 2007 who
have achieved grades higher than 7.
SELECT DISTINCT name, last_name Result
FROM student, enrolment name last_name
WHERE student.id_s = enrolment.FK_student David Novak
Maja Krajnc
AND date_of_birth > '2007-12-31' Maja Krajnc
AND grade > 7; Maja Malič

Enrolment
year_of_enr
id_e grade FK_Student FK_Course
olment
1 8 2026/2027 1 1
student 2 7 2026/2027 1 2
last_nam 3 9 2026/2027 2 4
id_s name enrolment_nr date_of_birth
e 4 9 2026/2027 2 5
1 David Novak E9320376041 12.12.2008 5 NULL 2026/2027 3 1
2 Maja Krajnc E3107410974 15.03.2008 6 10 2026/2027 3 3
3 Ales Novak E1234464687 NULL 219
7 6 2025/2026 4 6
4 Maja Malič E2137410974 15.05.2009 8 8 2025/2026 4 7

Merging more than 2 tables at the same time


• We would like to see a list of the names of students born after 2007 who
have achieved grades higher than 7 in courses with more than 5 ECTS points.
SELECT DISTINCT name, last_name
FROM student, enrolment, course
WHERE student.id_s = enrolment.FK_student
AND course.id_c = enrolment.FK_course Result
AND date_of_birth > '2007-12-31' last_na
name
me
AND grade > 7 Maja Krajnc
AND ects_points > 5; Maja Malič

student Enrolment
last_na enrolment_ date_of_birt Course year_of_enr
id_s name
me nr h id_c course_code course_title ects_points id_e grade
olment
FK_Student FK_Course
E932037604 1 62V108 Databases I 5 1 8 2026/2027 1 1
1 David Novak 12.12.2008
1 2 61V013 Computer networks 5 2 7 2026/2027 1 2
E310741097 Information systems 3 9 2026/2027 2 4
2 Maja Krajnc 15.03.2008 3 62V014 5
4 architectures 4 9 2026/2027 2 5
E123446468 4 V035 Quality management 5 5 NULL 2026/2027 3 1
3 Ales Novak NULL
7 5 V274 Performance marketing 6 6 10 2026/2027 3 3
E213741097 6 U0003 Roman law 8 7 6 2025/2026 4 220 6
4 Maja Malič 15.05.2009
4 7 U005 Substantive criminal law 8 8 8 2025/2026 4 7

16
09/05/2025

Sorting results (ORDER BY)


SELECT A1, A2, ... An  list of columns (attributes) to be displayed
FROM T1, T2, ..., Tm  list of tables from which to extract data
WHERE conditions  conditions that specify what data we want to see
ORDER BY A2  order of the results according to the selected column
• ASC - default value
• DESC - ranking from largest to smallest

• Multi-column sorting (ORDER BY A2 DESC, A1 ASC) also works

221

ORDER BY
• We want a list of grades, courses and students' names so
that the highest grades are the highest on the list. Result
name last_name grade course_title
SELECT name, last_name, grade, course_title
Ales Novak 10 Information systems architectures
FROM student, enrolment, course
Maja Krajnc 9 Quality management
WHERE student.id_s = enrolment.FK_student Maja Krajnc 9 Performance marketing
AND course.id_c = enrolment.FK_course David Novak 8 Databases I
Maja Malič 8 Substantive criminal law
ORDER BY grade DESC; David Novak 7 Computer networks
Maja Malič 6 Roman law
Ales Novak NULL Databases I

student
Course Enrolment
last_na enrolment_ date_of_birt
id_s name year_of_enr
me nr h id_c course_code course_title ects_points id_e grade FK_Student FK_Course
1 62V108 Databases I 5 olment
E932037604
1 David Novak 12.12.2008 1 8 2026/2027 1 1
1 2 61V013 Computer networks 5
E310741097 Information systems 2 7 2026/2027 1 2
2 Maja Krajnc 15.03.2008 3 62V014 5 3 9 2026/2027 2 4
4 architectures
E123446468 4 V035 Quality management 5 4 9 2026/2027 2 5
3 Ales Novak NULL 5 NULL 2026/2027 3 1
7 5 V274 Performance marketing 6
E213741097 6 U0003 Roman law 8 6 10 2026/2027 3 3
4 Maja Malič 15.05.2009 222
4 7 U005 Substantive criminal law 8 7 6 2025/2026 4 6
8 8 2025/2026 4 7

17
09/05/2025

LIMIT
• We would like to see a printout of the first three enrolled courses with more
than 3 ECTS points. Result
SELECT id_c, course_title, ects_points id_c course_title ects_points
1 Databases I 5
FROM course 2 Computer networks 5
WHERE ects_points > 3 3 Information systems architectures 5

ORDER BY id_c ASC


LIMIT 3;

Course
id_c course_code course_title ects_points
1 62V108 Databases I 5
2 61V013 Computer networks 5
Information systems
3 62V014 5
architectures
4 V035 Quality management 5
5 V274 Performance marketing 6
6 U0003 Roman law 8 223
7 U005 Substantive criminal law 8

Computational and text operations


In SELECT we can perform computational operations that are printed in
the query result. For example, we can use addition, subtraction, division,
multiplication, in the case of character expressions, concatenation, etc.
Some examples are listed in the tables:
SQL Operations on text
SQL Calculation operation CONCAT() Merge multiple cells
%, MOD Modulo LCASE() /
Convert to lowercase text
* Multiplication LOWER()
UCASE() /
+ Adding Convert to uppercase text
UPPER()
- Subtraction / change of sign
Convert text or number to
/ Sharing HEX()
hexadecimal notation
DIV Integer division
LENGTH() Print the length of the text
SUBSTRING() Prints part of the text as defined

224

18
09/05/2025

Computational and text operations


• Example of a calculation operation. Result
SELECT course_name, grade, points_ECTS, course_title
Databases I
grade
8
ECTS points
5.0
fictional
4.0

ects_points*(grade/10) AS 'fictional' Computer networks


Quality management
7
9
5.0
5.0
3.5
4.5

FROM enrolment, course


Performance marketing 9 6.0 5.4
Databases I NULL 5.0 NULL
Information systems
WHERE course.id_c = enrolment.FK_course; architectures
10 5.0 5.0
Roman law 6 8.0 4.8
• Example of operation on text. Substantive criminal law 8 8.0 6.4

SELECT course_title, year_of_enrolment, CONCAT(course_title, ' -> ',


year_of_enrolment)
FROM enrolment, course
WHERE course.id_c = enrolment.FK_course AND id_c < 3;
Course Enrolment
id_c course_code course_title ects_points year_of_enr Result
1 62V108 Databases I 5 id_e grade FK_Student FK_Course year_of_enr CONCAT(course_title, ' ->
olment course_title
2 61V013 Computer networks 5 1 8 2026/2027 1 1 olment ', year_of_enrolment)
3 62V014
Information systems
5 2 7 2026/2027 1 2 Databases I 2026/2027 Databases I -> 2020 / 2021
architectures 3 9 2026/2027 2 4 Databases I 2026/2027 Databases I -> 2020 / 2021
4 V035 Quality management 5 4 9 2026/2027 2 5 Computer networks Computer networks ->
2026/2027
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1 2020 / 2021
6 U0003 Roman law 8 6 10 2026/2027 3 3 225
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6

Selecting columns when merging tables


• If two joined tables have the same attribute name (e.g. if we have
several code lists and all of them have the "name" attribute or if all
tables have an identifier named "ID"), we must also write in the SELECT
statement which selected table we want the columns to be extracted
from in the FROM statement.

SELECT student.name, enrolment.grade


FROM student, enrolment
WHERE student.id_s=en.FK_student;

226

19
09/05/2025

Naming of tables
• Where SELECT statements are long, it makes sense to rename the table to FROM with
shorter tags used throughout the SELECT statement.
• We would like to see a list of the names of students born after 2007 who have achieved
grades higher than 7 in courses with more than 5 ECTS points.
SELECT DISTINCT S.name AS ‘ Student’s name', S.last_name AS ‘ Student’s
last_name'
FROM student S, enrolment V, course P
WHERE S.id_s = V.FK_student Result
AND P.id_c = V.FK_course Student's name Student's last_name
Maja Krajnc
AND date_of_birth > '2007-12-31' Maja Malič
AND grade > 7
AND ects_points > 5;
student Enrolment
last_na enrolment_ date_of_birt Course year_of_enr
id_s name id_e grade FK_Student FK_Course
me nr h id_c course_code course_title ects_points olment
E932037604 1 62V108 Databases I 5 1 8 2026/2027 1 1
1 David Novak 12.12.2008 2 7 2026/2027 1 2
1 2 61V013 Computer networks 5
E310741097 Information systems 3 9 2026/2027 2 4
2 Maja Krajnc 15.03.2008 3 62V014 5
4 architectures 4 9 2026/2027 2 5
E123446468 4 V035 Quality management 5 5 NULL 2026/2027 3 1
3 Ales Novak NULL
7 5 V274 Performance marketing 6 6 10 2026/2027 3 3
E213741097 6 U0003 Roman law 8 7 6 2025/2026 4 227 6
4 Maja Malič 15.05.2009
4 7 U005 Substantive criminal law 8 8 8 2025/2026 4 7

228

20
09/05/2025

Operation IN / NOT IN  / 
• We check whether a certain cell in the table belongs to a
certain set.
• WHERE attribute IN (value1, value2)
• There is also NOT IN, which checks whether a particular cell in
the table does not belong to any value in the set.
• We want to see a list of courses with 5 or 8 ECTS points.
Result
SELECT * id_c course_code course_title ects_points
FROM course 1
2
62V108
61V013
Databases I
Computer networks
5
5
WHERE ects_points IN (5,8); 3 62V014 Information systems architectures 5
4 V035 Quality management 5
Course
6 U0003 Roman law 8
id_c course_code course_title ects_points
7 U005 Substantive criminal law 8
1 62V108 Databases I 5
2 61V013 Computer networks 5
Information systems
3 62V014 5
architectures
4 V035 Quality management 5
5 V274 Performance marketing 6
6 U0003 Roman law 8
229
7 U005 Substantive criminal law 8

Nested clauses in WHERE, IN


 Nested statements allow you to specify a set in which to check for the existence of an
attribute.
• We would like to see a list of the titles of courses in  Same sentence as on the left without nested base,
which students are enrolled and have received grades but not always without nested saves:
higher than 7.
SELECT id_c, course_title
SELECT id_c, course_title
FROM course, enrolment
FROM course
WHERE id_c IN WHERE course.id_c = enrolment.FK_course
(SELECT FK_course AND grade > 7;
FROM enrolment
WHERE grade > 7);
Course Enrolment
ects_point
id_c course_code course_title year_of_enr
s id_e grade FK_Student FK_Course Result
olment
1 62V108 Databases I 5 id_c course_title
1 8 2026/2027 1 1
2 61V013 Computer networks 5 1 Databases I
2 7 2026/2027 1 2
Information systems 3 Information systems architectures
3 62V014 5 3 9 2026/2027 2 4
architectures 4 Quality management
4 9 2026/2027 2 5
4 V035 Quality management 5 5 Performance marketing
5 NULL 2026/2027 3 1
5 V274 Performance marketing 6 7 Substantive criminal law
6 10 2026/2027 3 3
6 U0003 Roman law 8 230
7 6 2025/2026 4 6
7 U005 Substantive criminal law 8
8 8 2025/2026 4 7

21
09/05/2025

Nested statements in WHERE, IN , NOT IN


• We would like to see the titles of courses where students have received grades higher than 6, not in
2025/2026.

SELECT id_c, course_title


FROM course
WHERE id_c IN
(SELECT FK_course FROM enrolment WHERE grade > 6)
AND NOT id_c IN
(SELECT FK_course FROM enrolment WHERE year_of_enrolment =
'2025/2026');
Enrolment
Result
Course year_of_enr
id_e grade FK_Student FK_Course id_c course_title
id_c course_code course_title ects_points olment
1 Databases I
1 62V108 Databases I 5 1 8 2026/2027 1 1
2 Computer networks
2 61V013 Computer networks 5 2 7 2026/2027 1 2
3 Information systems architectures
Information systems 3 9 2026/2027 2 4
3 62V014 5 4 Quality management
architectures 4 9 2026/2027 2 5
5 Performance marketing
4 V035 Quality management 5 5 NULL 2026/2027 3 1
5 V274 Performance marketing 6 6 10 2026/2027 3 3
6 U0003 Roman law 8 7 6 2025/2026 4 6 231
7 U005 Substantive criminal law 8 8 8 2025/2026 4 7

Operation EXISTS / NOT EXISTS


• We check whether a certain cell in the table belongs to a certain
set.
• WHERE EXISTS (new statement defining sets).
• EXISTS checks if the nested statement returns at least 1 line, then it is
TRUE, otherwise FALSE.
• IN can be used without nested statements, but they are mandatory in
EXISTS.
• There is also a NOT EXISTS, where we check if a certain cell of the table
does not belong to any value in the set.

232

22
09/05/2025

Nested statements in WHERE, EXISTS, NOT EXISTS


• We would like to see the titles of courses where students have received grades higher than 6, not in
2025/2026.
SELECT id_c, course_title
FROM course
WHERE EXISTS
(SELECT * FROM enrolment WHERE enrolment.FK_course = course.id_c AND grade >
6)
AND NOT EXISTS
(SELECT * FROM enrolment WHERE enrolment.FK_course = course.id_c AND
year_of_enrolment = '2025/2026');

Course Enrolment Result


id_c course_code course_title ects_points id_e year_of_enr id_c course_title
grade FK_Student FK_Course 1 Databases I
1 62V108 Databases I 5 olment
2 61V013 Computer networks 5 1 8 2026/2027 1 1 2 Computer networks
Information systems 2 7 2026/2027 1 2 3 Information systems architectures
3 62V014 5 3 9 2026/2027 2 4 4 Quality management
architectures
4 V035 Quality management 5 4 9 2026/2027 2 5 5 Performance marketing
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1
6 U0003 Roman law 8 6 10 2026/2027 3 3 233
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6
8 8 2025/2026 4 7

Operation ANY / SOME


• We check whether a certain cell in the table belongs to a certain
set.
• WHERE attribute >/=/... ANY (a new statement specifying sets, which
must return only one attribute to be compared).
• ANY checks if the nested statement returns at least 1 line, then it is
TRUE, otherwise FALSE.
• You can also use the SOME command.
• In ANY, nested statements are optional, but comparison operators are
used, unlike EXISTS.

234

23
09/05/2025

Nested clauses in WHERE, ANY


• We would like to see the titles of courses where students have received grades higher
than 6, not in 2025/2026.
SELECT id_c, course_title
FROM course
WHERE
id_c = ANY
(SELECT FK_course FROM enrolment WHERE grade > 6)
AND NOT id_c = ANY
(SELECT FK_course FROM enrolment WHERE year_of_enrolment =
'2025/2026');
Enrolment
Course year_of_enr Result
id_e grade FK_Student FK_Course
id_c course_code course_title ects_points olment id_c course_title
1 62V108 Databases I 5 1 8 2026/2027 1 1 1 Databases I
2 61V013 Computer networks 5 2 7 2026/2027 1 2 2 Computer networks
Information systems 3 9 2026/2027 2 4 3 Information systems architectures
3 62V014 5
architectures 4 9 2026/2027 2 5 4 Quality management
4 V035 Quality management 5 5 NULL 2026/2027 3 1 5 Performance marketing
5 V274 Performance marketing 6 6 10 2026/2027 3 3
6 U0003 Roman law 8 7 6 2025/2026 4 6 235
7 U005 Substantive criminal law 8 8 8 2025/2026 4 7

Operation ALL
• We check whether a certain cell in the table belongs to a
certain set.
• WHERE attribute >/=/... ALL (a new statement specifying sets
that must return only one attribute to be compared).
• ALL checks if the nested statement returns ALL lines, then it
is TRUE, otherwise FALSE.
• In ALL, nested statements are optional, but comparison
operators are used as in ANY.

236

24
09/05/2025

Nested clauses in WHERE, ALL


• We would like to see a list of course titles where students have
obtained a grade higher than 9, but not in 2025/2026.
SELECT id_c, course_title
FROM course Result
WHERE id_c = id_c course_title
3 Information systems architectures
ALL (SELECT FK_course FROM enrolment WHERE grade > 9)
AND NOT id_c = ALL (SELECT FK_course FROM enrolment
WHERE year_of_enrolment = '2025/2026');

Course Enrolment
id_c course_code course_title ects_points id_e year_of_enr
grade FK_Student FK_Course
1 62V108 Databases I 5 olment
2 61V013 Computer networks 5 1 8 2026/2027 1 1
Information systems 2 7 2026/2027 1 2
3 62V014 5 3 9 2026/2027 2 4
architectures
4 V035 Quality management 5 4 9 2026/2027 2 5
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1
6 U0003 Roman law 8 6 10 2026/2027 3 3
237
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6
8 8 2025/2026 4 7

Operation UNION A  B
• The union combines all elements from set A and elements from set B into set C.
• Eliminate repeating elements when using the UNION command and keep repeating
elements when using the UNION ALL command.
• Used over two or more SELECT statements.
SELECT name AS name FROM student Result
name
UNION ALL Ales
Information systems architectures
SELECT course_title AS name FROM course David
Performance marketing
ORDER BY name; Substantive criminal law
Maja
Maja
student Quality management
Course Databases I
last_na enrolment_ date_of_birt
id_s name Computer networks
me nr h id_c course_code course_title ects_points
Roman law
E932037604 1 62V108 Databases I 5
1 David Novak 12.12.2008
1 2 61V013 Computer networks 5
E310741097 Information systems
2 Maja Krajnc 15.03.2008 3 62V014 5
4 architectures
E123446468 4 V035 Quality management 5
3 Ales Novak NULL
7 5 V274 Performance marketing 6
E213741097 6 U0003 Roman law 8 238
4 Maja Malič 15.05.2009
4 7 U005 Substantive criminal law 8

25
09/05/2025

Operation INTERSECT A  B
• The intersection combines only the elements from set A and
the elements from set B that appear in both sets.
• Eliminates repeated elements when using the INTERSECT
command. INTERSECT is not supported in MySQL.
• Used over two or more SELECT statements.  It is not supported in MySQL, so it
can be solved with the following
statement:
SELECT grade FROM enrolment Result SELECT DISTINCT grade FROM
grade
INTERSECT 6 enrolment
SELECT ects_points FROM course; 8
WHERE grade IN
(SELECT ects_points FROM course);
Course Enrolment
id_c course_code course_title ects_points year_of_enr
id_e grade FK_Student FK_Course
1 62V108 Databases I 5 olment
2 61V013 Computer networks 5 1 8 2026/2027 1 1
Information systems 2 7 2026/2027 1 2
3 62V014 5 3 9 2026/2027 2 4
architectures
4 V035 Quality management 5 4 9 2026/2027 2 5
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1
6 U0003 Roman law 8 6 10 2026/2027 3 3 239
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6
8 8 2025/2026 4 7

Operation EXCEPT / MINUS A \ B


• The difference returns all elements of set A that do not appear in
set B. A \ B ≠ B \ A.
• Eliminates repeated elements when using the EXCEPT command.
EXCEPT is not supported in MySQL.
• Used over two or more SELECT statements.  It is not supported in MySQL, so it
can be solved with the following
statement:
SELECT grade FROM enrolment Result
SELECT DISTINCT grade FROM
grade
EXCEPT 7 enrolment
9
SELECT ects_points FROM course; 10 WHERE grade NOT IN
Enrolment
(SELECT ects_points FROM course);
Course
id_c course_code course_title ects_points id_e year_of_enr
grade FK_Student FK_Course
1 62V108 Databases I 5 olment
2 61V013 Computer networks 5 1 8 2026/2027 1 1
Information systems 2 7 2026/2027 1 2
3 62V014 5 3 9 2026/2027 2 4
architectures
4 V035 Quality management 5 4 9 2026/2027 2 5
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1
6 U0003 Roman law 8 6 10 2026/2027 3 3
240
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6
8 8 2025/2026 4 7

26
09/05/2025

Merging tables
INNER / INNER OUTER / OUTER JOIN
JOIN ⋈
• CLASSIC
• EXPLICIT
LEFT OUTER JOIN RIGHT OUTER JOIN FULL OUTER JOIN
• IMPLICIT

• NATURAL JOIN
• CROSS JOIN
SQL - DML
SELECT * FROM table1 LEFT JOIN SELECT * FROM table1 RIGHT JOIN SELECT * FROM table1 FULL OUTER
table2 ON table1.ID_table1 = table2 ON table1.ID_table1 = JOIN table2 ON table1.ID_table1 =
table2.FK_table1; table2.FK_table1; table2.FK_table1;
SELECT * FROM table1 JOIN
table2 ON table1.ID_table1 =
table2.FK_table1

Internal table joins / INNER JOIN ⋈


• Returns all rows from both tables where there is a match between the columns (usually
merging them
via the primary key ID and the foreign key TK).
• You can also merge multiple tables at the same time.
• Types:
• CLASSIC
• Explicit and implicit grouping is the same in content, the difference is in the syntax.
• EXPLICIT
SELECT * FROM table1 INNER JOIN table2 ON table1.ID_table1 = table2.FK_table1 WHERE conditions;
• IMPLICIT
SELECT * FROM table1, table2 WHERE table1.ID_table1 = table2.FK_table1 AND conditions;
• NATURAL CONTACT / NATURAL JOIN ⋈
• Automatically merges two tables if the attributes in the two tables have the same name.
SELECT * FROM table1 NATURAL JOIN table2 WHERE conditions;
(the name of the primary key in Table 1 must be the same as the name of the foreign key in Table 2)

• CARTESIAN PRODUCT / CROSS JOIN 


• Connects each row in the first table to each row in the second table.
SELECT * FROM table1 CROSS JOIN table2 WHERE conditions; 242

27
09/05/2025

External table merging / OUTER JOIN


• LEFT OUTER JOIN
• Returns all rows from the table that is written on the left side of the LEFT JOIN statement,
even if there are no hits to it in the right table (NULL values are printed there).
SELECT * FROM table1 LEFT OUTER JOIN table2 ON table1.ID_table1 = table2.FK_table1;

• RIGHT OUTER JOIN


• Returns all rows from the table written on the right side of the RIGHT JOIN statement, even
if there are no hits to it in the left table (NULL values are printed there).
SELECT * FROM table1 RIGHT OUTER JOIN table2 ON table1.ID_table1 = table2.FK_table1;

• FULL OUTER JOIN ⋈


• Returns all rows from both tables, but where there are no hits in one table, outputs NULL
values.
• FULL OUTER JOIN is not supported in MySQL, but you can combine LEFT JOIN  RIGHT
JOIN. It would work in other DBMS:
SELECT * FROM table1 FULL OUTER JOIN table2 ON table1.ID_table1 = table2.FK_table1;

243

INNER JOIN
• We want to see a printout of students who have  The identical result is obtained by:
received a grade higher than 7.
SELECT *
SELECT *
FROM student
FROM student, enrolment
INNER JOIN enrolment
ON student.id_s = enrolment.FK_student
WHERE grade > 7; WHERE student.id_s = enrolment.FK_student
• INNER can be omitted because it is the default AND grade > 7;
JOIN in SQL.
student Enrolment
Result
last_na enrolment_ date_of_birt year_of_enr
id_s name id_e grade FK_Student FK_Course last_nam date_of_birt gra year_of_enrolm
me nr h olment id_s name enrolment_nr id_e id_c
e h de ent
E932037604 1 8 2026/2027 1 1
1 David Novak 12.12.2008 1 David Novak E9320376041 12.12.2008 1 8 2026/2027 1
1 2 7 2026/2027 1 2
2 Maja Krajnc E3107410974 15.03.2008 3 9 2026/2027 4
E310741097 3 9 2026/2027 2 4
2 Maja Krajnc 15.03.2008 2 Maja Krajnc E3107410974 15.03.2008 4 9 2026/2027 5
4 4 9 2026/2027 2 5
3 Ales Novak E1234464687 NULL 6 10 2026/2027 3
E123446468 5 NULL 2026/2027 3 1
3 Ales Novak NULL 4 Maja Malič E2137410974 15.05.2009 8 8 2025/2026 7
7 6 10 2026/2027 3 3
E213741097 7 6 2025/2026 4 6 244
4 Maja Malič 15.05.2009
4 8 8 2025/2026 4 7

28
09/05/2025

INNER JOIN - 3 tables


• We would like to see a list of the names of students born after
2007 who have achieved grades higher than 7 in courses with  The identical result is obtained by:
more than 5 ECTS points.
SELECT DISTINCT name, last_name SELECT DISTINCT name, last_name
FROM student FROM student, enrolment, course
JOIN enrolment ON student.id_s = enrolment.FK_student WHERE student.id_s = enrolment.FK_student
JOIN course ON course.id_c = enrolment.FK_course AND course.id_c = enrolment.FK_course
WHERE date_of_birth > '2007-12-31'
AND date_of_birth > '2007-12-31'
AND grade > 7
AND grade > 7
AND ects_points > 5; Result
last_nam AND ects_points > 5;
name
e
student Maja Krajnc Enrolment
last_na enrolment_ date_of_birt Course Maja Malič year_of_enr
id_s name id_e grade FK_Student FK_Course
me nr h id_c course_code course_title ects_points olment
E932037604 1 62V108 Databases I 5 1 8 2026/2027 1 1
1 David Novak 12.12.2008 2 7 2026/2027 1 2
1 2 61V013 Computer networks 5
E310741097 Information systems 3 9 2026/2027 2 4
2 Maja Krajnc 15.03.2008 3 62V014 5
4 architectures 4 9 2026/2027 2 5
E123446468 4 V035 Quality management 5 5 NULL 2026/2027 3 1
3 Ales Novak NULL
7 5 V274 Performance marketing 6 6 10 2026/2027 3 3
E213741097 6 U0003 Roman law 8 7 6 2025/2026 4 245 6
4 Maja Malič 15.05.2009
4 7 U005 Substantive criminal law 8 8 8 2025/2026 4 7

INNER JOIN
• We would like a list of courses, ECTS points, grades
and year of enrolment. Result
year_of_enrol
SELECT P.id_c, course_title, id_c course_title ects_points grade ment
points_ECTS, grade, year_of_enrolment 1 Databases I 5 8 2026/2027
2 Computer networks 5 7 2026/2027
FROM course P 4 Quality management 5 9 2026/2027
5 Performance marketing 6 9 2026/2027
JOIN enrolment V 1 Databases I 5 NULL 2026/2027
ON P.id_c = V.FK_course; 3
Information systems
architectures
5 10 2026/2027
6 Roman law 8 6 2025/2026
7 Substantive criminal law 8 8 2025/2026

Course Enrolment
id_c course_code course_title ects_points id_e year_of_enr
grade FK_Student FK_Course
1 62V108 Databases I 5 olment
2 61V013 Computer networks 5 1 8 2026/2027 1 1
Information systems 2 7 2026/2027 1 2
3 62V014 5
architectures 3 9 2026/2027 2 4
4 V035 Quality management 5 4 9 2026/2027 2 5
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1
6 U0003 Roman law 8 6 10 2026/2027 3 3
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6 246
8 0196 Systems theory 7 8 8 2025/2026 4 7

29
09/05/2025

LEFT OUTER JOIN


• We would like a list of courses, ECTS points, grades
and year of enrolment, including courses in which
no one is enrolled. Result
year_of_enrol
SELECT P.id_c, course_title, id_c course_title ects_points grade ment
points_ECTS, grade, year_enrolled 1 Databases I 5 8 2026/2027
1 Databases I 5 NULL 2026/2027
FROM course P 2 Computer networks 5 7 2026/2027
Information systems
LEFT JOIN enrolment V 3
architectures
5 10 2026/2027
4 Quality management 5 9 2026/2027
ON P.id_c = V.FK_course; 5 Performance marketing 6 9 2026/2027
6 Roman law 8 6 2025/2026
7 Substantive criminal law 8 8 2025/2026
8 Systems theory 7 NULL NULL

Course Enrolment
id_c course_code course_title ects_points id_e year_of_enr
grade FK_Student FK_Course
1 62V108 Databases I 5 olment
2 61V013 Computer networks 5 1 8 2026/2027 1 1
Information systems 2 7 2026/2027 1 2
3 62V014 5 3 9 2026/2027 2 4
architectures
4 V035 Quality management 5 4 9 2026/2027 2 5
5 V274 Performance marketing 6 5 NULL 2026/2027 3 1
6 U0003 Roman law 8 6 10 2026/2027 3 3
7 U005 Substantive criminal law 8 7 6 2025/2026 4 6 247
8 0196 Systems theory 7 8 8 2025/2026 4 7

RIGHT OUTER JOIN


• We would like to see a list of courses, ECTS points,
grades and year of enrolment, including
enrolments where students have not yet chosen a Result
course. year_of_enrol
id_c course_title ects_points grade ment
SELECT P.id_c, course_title, 1 Databases I 5 8 2026/2027
points_ECTS, grade, year_enrolled 2
4
Computer networks
Quality management
5
5
7
9
2026/2027
2026/2027
FROM course P 5 Performance marketing 6 9 2026/2027
1 Databases I 5 NULL 2026/2027
RIGHT JOIN enrolment V 3
Information systems
5 10 2026/2027
architectures
ON P.id_c = V.FK_course; 6 Roman law 8 6 2025/2026
7 Substantive criminal law 8 8 2025/2026
NULL NULL NULL NULL 2026/2027
Enrolment
Course year_of_enr
id_e grade FK_Student FK_Course
id_c course_code course_title ects_points olment
1 62V108 Databases I 5 1 8 2026/2027 1 1
2 61V013 Computer networks 5 2 7 2026/2027 1 2
Information systems 3 9 2026/2027 2 4
3 62V014 5
architectures 4 9 2026/2027 2 5
4 V035 Quality management 5 5 NULL 2026/2027 3 1
5 V274 Performance marketing 6 6 10 2026/2027 3 3
6 U0003 Roman law 8 7 6 2025/2026 4 6
7 U005 Substantive criminal law 8 8 8 2025/2026 4 7 248
8 0196 Systems theory 7 9 NULL 2026/2027 1 NULL

30
09/05/2025

FULL OUTER JOIN, UNION


• We would like to see a list of courses, ECTS points, grades and year of enrolment,
including courses where no one is enrolled and including enrolments where
students have not yet chosen a course. Result
year_of_en
SELECT P.id_c, course_title, points_ECTS, grade, year_of_enrolment id_c course_title ects_points grade rolment
FROM course P LEFT JOIN enrolment V 1 Databases I 5 8 2026/2027
1 Databases I 5 NULL 2026/2027
ON P.id_c = V.id_c 2 Computer networks 5 7 2026/2027
UNION 3
Information systems
5 10 2026/2027
architectures
SELECT P.id_c, course_title, points_ECTS, grade, year_of_enrolment 4 Quality management 5 9 2026/2027
FROM course P RIGHT JOIN enrolment V 5 Performance marketing 6 9 2026/2027
6 Roman law 8 6 2025/2026
ON P.id_c = V.id_c; 7 Substantive criminal law 8 8 2025/2026
8 Systems theory 7 NULL NULL
NULL NULL NULL NULL 2026/2027
Enrolment
Course year_of_enr
id_e grade FK_Student FK_Course
id_c course_code course_title ects_points olment
1 62V108 Databases I 5 1 8 2026/2027 1 1
2 61V013 Computer networks 5 2 7 2026/2027 1 2
Information systems 3 9 2026/2027 2 4
3 62V014 5
architectures 4 9 2026/2027 2 5
4 V035 Quality management 5 5 NULL 2026/2027 3 1
5 V274 Performance marketing 6 6 10 2026/2027 3 3
6 U0003 Roman law 8 7 6 2025/2026 4 6
7
8
U005
0196
Substantive criminal law
Systems theory
8
7
8
9
8
NULL
2025/2026 4
2026/2027 1
7
249
NULL
249

Aggregate functions
• Aggregate functions perform a computational operation on
data from one column and return one row as the result. SELECT A1, A2, ... An
• MIN
• Minimum value in column FROM T1, T2, ..., Tm
• MAX WHERE condition
• Maximum value in a column
• SUM GROUP BY columns
• Sum of all values in a column
HAVING conditions
• AVG
• Average of all values in a column
• COUNT They are only used in conjunction
• The number of total values in a given column with aggregate functions.
• If we add COUNT DISTINCT A1, we get the number of different values
in column A1. The same can be applied to AVG and SUM.

251

31
09/05/2025

MAX, MIN
• We want to see the highest grade.
Result
SELECT MAX(grade) 10
FROM enrolment;
• We want to see a minimum of ECTS credits in courses where
students have already received grades.
SELECT MIN(ects_points)
FROM enrolment, course Result
WHERE course.id_c = enrolment.FK_course 5
AND grade IS NOT NULL;
Enrolment
Course year_of_enr
id_e grade FK_Student FK_Course
id_c course_code course_title ects_points olment
1 62V108 Databases I 5 1 8 2026/2027 1 1
2 61V013 Computer networks 5 2 7 2026/2027 1 2
Information systems 3 9 2026/2027 2 4
3 62V014 5
architectures 4 9 2026/2027 2 5
4 V035 Quality management 5 5 NULL 2026/2027 3 1
5 V274 Performance marketing 6 6 10 2026/2027 3 3
6 U0003 Roman law 8 7 6 2025/2026 4 6
7 U005 Substantive criminal law 8 8 8 2025/2026 4 7 252
8 0196 Systems theory 7 9 NULL 2026/2027 1 NULL

SUM
• Let's write down the sum of the unique ECTS points assigned to the
courses on IDs 1-5.
SELECT SUM(DISTINCT ects_points)
FROM course Result
WHERE id_c < 6; 11

Course
id_c course_code course_title ects_points
1 62V108 Databases I 5
2 61V013 Computer networks 5
Information systems
3 62V014 5
architectures
4 V035 Quality management 5
5 V274 Performance marketing 6
6 U0003 Roman law 8
7 U005 Substantive criminal law 8
8 0196 Systems theory 7 253

32
09/05/2025

AVG
• Let's list the average number of ECTS credits for the courses students enrolled in
during the academic year 2026/2027.
SELECT AVG(ects_points) FROM enrolment, course
Result
WHERE enrolment.FK_course = course.id_c AND year_of_enrolment =
'2026/2027'; 5.1667
Warning! The above sentence counts 3x if 3 students are enrolled in the
course.
SELECT AVG(ects_points)
FROM course
Result
WHERE id_c IN
5.2000
(SELECT DISTINCT FK_course
FROM enrolment
WHERE year_of_enrolment = '2026/2027'); Enrolment
year_of_enr
Course id_e grade FK_Student FK_Course
olment
id_c course_code course_title ects_points 1 8 2026/2027 1 1
1 62V108 Databases I 5 2 7 2026/2027 1 2
2 61V013 Computer networks 5 3 9 2026/2027 2 4
Information systems 4 9 2026/2027 2 5
3 62V014 5
architectures 5 NULL 2026/2027 3 1
4 V035 Quality management 5 6 10 2026/2027 3 3
5 V274 Performance marketing 6 7 6 2025/2026 4 6
6 U0003 Roman law 8 8 8 2025/2026 4 7
7 U005 Substantive criminal law 8 254
9 NULL 2026/2027 1 NULL
8 0196 Systems theory 7

COUNT(*) / COUNT(A1)
• Let's list how many courses have more than 6 ECTS points. Result
SELECT COUNT(*) 3
FROM course
WHERE ects_points > 6;
• Let's list the number of courses that students have enrolled in
2026/2027.
SELECT COUNT(DISTINCT FK_course) Result
FROM enrolment 5
WHERE year_of_enrolment = '2026/2027'; Enrolment
year_of_enr
id_e grade FK_Student FK_Course
Course olment
id_c course_code course_title ects_points 1 8 2026/2027 1 1
1 62V108 Databases I 5 2 7 2026/2027 1 2
2 61V013 Computer networks 5 3 9 2026/2027 2 4
Information systems 4 9 2026/2027 2 5
3 62V014 5
architectures 5 NULL 2026/2027 3 1
4 V035 Quality management 5 6 10 2026/2027 3 3
5 V274 Performance marketing 6 7 6 2025/2026 4 6
6 U0003 Roman law 8 8 8 2025/2026 4 7
7 U005 Substantive criminal law 8 9 NULL 2026/2027 1 NULL 255
8 0196 Systems theory 7

33
09/05/2025

GROUP BY
• Where only the aggregate function MIN / MAX / AVG / SUM / COUNT is
entered in SELECT and 1 attribute inside the parentheses (for COUNT it can
also be * instead of an attribute), the result is correct because it only selects
the highest / average value etc. from ONE COLUMN.
• But if we want to print next to that column the highest value, we MUST also
use GROUP BY.
• GROUP BY is used to group the results according to the specified
column(s).

256

GROUP BY, SUM


• Let's list how many ECTS points all students have accumulated together in each
academic year.
Result
SELECT year_of_enrolment, SUM(ects_points) AS 'Number of ECTS points' year_of_enro Number of ECTS
FROM course, enrolment lment points
WHERE course.id_c = enrolment.FK_course; 2026/2027 47

SELECT year_of_enrolment, SUM(ects_points) AS 'Number of ECTS points'


Result
FROM course, enrolment year_of_enro Number of ECTS
WHERE course.id_c = enrolment.FK_course lment points
2026/2027 31
GROUP BY enrolment.year_of_enrolment;
2025/2026 16

Enrolment
Course year_of_enr
id_e grade FK_Student FK_Course
id_c course_code course_title ects_points olment
1 62V108 Databases I 5 1 8 2026/2027 1 1
2 61V013 Computer networks 5 2 7 2026/2027 1 2
Information systems 3 9 2026/2027 2 4
3 62V014 5 4 9 2026/2027 2 5
architectures
4 V035 Quality management 5 5 NULL 2026/2027 3 1
5 V274 Performance marketing 6 6 10 2026/2027 3 3
6 U0003 Roman law 8 7 6 2025/2026 4 6
7 U005 Substantive criminal law 8 8 8 2025/2026 4 7 257
8 0196 Systems theory 7 9 NULL 2026/2027 1 NULL

34
09/05/2025

GROUP BY, ORDER BY, COUNT


• List the number of students enrolled in each course (alphabetical order).
SELECT course_name, COUNT(*) AS 'Number of students' Result
Number of
FROM course, enrolment course_title
Information systems architectures
students
1
WHERE course.id_c = enrolment.FK_course Performance marketing
Substantive criminal law
1
1
GROUP BY enrolment.id_c Quality management 1
Databases I 2
ORDER BY course_title; Computer networks 1
Roman law 1
• Common mistake: without GROUP BY, the above result would print only the first course
and the sum of all students in the courses (we have more than just the agr. function
selected in SELECT)!
Enrolment
year_of_enr
Course id_e grade FK_Student FK_Course
olment
id_c course_code course_title ects_points
1 8 2026/2027 1 1
1 62V108 Databases I 5
2 7 2026/2027 1 2
2 61V013 Computer networks 5
3 9 2026/2027 2 4
Information systems
3 62V014 5 4 9 2026/2027 2 5
architectures
4 V035 Quality management 5 5 NULL 2026/2027 3 1
5 V274 Performance marketing 6 6 10 2026/2027 3 3
6 U0003 Roman law 8 7 6 2025/2026 4 6
7 U005 Substantive criminal law 8 8 8 2025/2026 4 7 258
8 0196 Systems theory 7 9 NULL 2026/2027 1 NULL

GROUP BY, COUNT


Result
last_nam Number of
name
e objects
David Novak 2
• List the number of each course the student has enrolled in. Maja Krajnc 3

SELECT name, last_name, COUNT(DISTINCT id_c), year_of_enrolment Ales


Maja
Novak
Malič
2
3
FROM student, enrolment
WHERE student.id_s = enrolment.FK_student
GROUP BY student.id_s;

• If we select an attribute in SELECT that is not in the table from which the attribute we are
grouping is taken, it will output 1 random value from all the results for that course and
student. PostgreSQL would otherwise not allow such a statement at all.
Enrolment
year_of_enr
id_e grade FK_Student FK_Course
olment
student 1 8 2026/2027 1 1
last_na enrolment_ date_of_birt 2 7 2026/2027 1 2
id_s name 3 9 2026/2027 2 4
me nr h
E932037604 4 9 2026/2027 2 5
1 David Novak 12.12.2008 5 NULL 2026/2027 3 1
1
E310741097 6 10 2026/2027 3 3
2 Maja Krajnc 15.03.2008 7 6 2025/2026 4 6
4
8 8 2025/2026 4 7
E123446468
3 Ales Novak NULL 9 NULL 2026/2027 1 NULL
7
10 9 2026/2027 2 1
E213741097 11 6 2026/2027 3 1 259
4 Maja Malič 15.05.2009
4 12 8 2026/2027 4 3

35
09/05/2025

GROUP BY, MAX


• Let's write down the maximum difference between the highest and lowest grade in the course.
SELECT MAX(max-min)
FROM(
SELECT course_title, MIN(grade) AS min, MAX(grade) AS max Result
MAX(max-min)
FROM course, enrolment 3
WHERE course.id_c = enrolment.FK_course
GROUP BY course.id_c) grades;
• When GROUP BY is used, it makes the most sense to use the grouping ID where possible,
otherwise having objects with the same name can lead to incorrect results!
Enrolment
year_of_enr
id_e grade FK_Student FK_Course
olment Course
1 8 2026/2027 1 1 id_c course_code course_title ects_points
2 7 2026/2027 1 2 1 62V108 Databases I 5
3 9 2026/2027 2 4
2 61V013 Computer networks 5
4 9 2026/2027 2 5
Information systems
5 NULL 2026/2027 3 1 3 62V014 5
architectures
6 10 2026/2027 3 3
7 6 2025/2026 4 6
4 V035 Quality management 5
8 8 2025/2026 4 7 5 V274 Performance marketing 6
9 NULL 2026/2027 1 NULL 6 U0003 Roman law 8
10 9 2026/2027 2 1 7 U005 Substantive criminal law 8 260
11 6 2026/2027 3 1 8 0196 Systems theory 7
12 8 2026/2027 4 3

Merging operations, AVG


• Let's calculate the difference between the average grades of the students in Database I, Computer Networks and
Information Systems Architecture, and Quality Management and Performance Marketing.
SELECT FERI.avg_grade - EPF.avg_grade
FROM
(SELECT AVG(grade) as avg_grade
FROM enrolment
WHERE enrolment.FK_course IN
(SELECT course.id_c FROM course WHERE id_c = 1 OR id_c = 2 OR id_c = 3)) AS FERI,
(SELECT AVG(grade) as avg_grade
FROM enrolment
WHERE enrolment.FK_course and
(SELECT course.id_c FROM course WHERE id_c = 4 OR id_c = 5)) AS EPF;
Enrolment
year_of_enro
id_e grade FK_Student FK_Course
lment Course
1 8 2026/2027 1 1 id_c course_code course_title ects_points
2 7 2026/2027 1 2 1 62V108 Databases I 5
Result
3 9 2026/2027 2 4 2 61V013 Computer networks 5 -1.0000
4 9 2026/2027 2 5
Information systems
5 NULL 2026/2027 3 1 3 62V014 5
architectures
6 10 2026/2027 3 3
7 6 2025/2026 4 6
4 V035 Quality management 5
8 8 2025/2026 4 7 5 V274 Performance marketing 6
9 NULL 2026/2027 1 NULL 6 U0003 Roman law 8
10 9 2026/2027 2 1 7 U005 Substantive criminal law 8 261
11 6 2026/2027 3 1 8 0196 Systems theory 7
12 8 2026/2027 4 3

36
09/05/2025

MIN / LIMIT primer


• Let's list the courses with the least ECTS points.
SELECT course_title, point_ECTS
Result
FROM course course_title ects_points
Databases I 5
ORDER BY ects_points
LIMIT 1;
SELECT course_title, point_ECTS Result
course_title ects_points
FROM course Databases I 5
Computer networks 5
WHERE ects_points = (SELECT MIN(ects_points) FROM Information systems architectures 5
course); Quality management 5
Course
id_c course_code course_title ects_points
A common mistake: choosing LIMIT instead of MIN or MAX 1 62V108 Databases I 5
2 61V013 Computer networks 5
does not give the right result, because LIMIT limits the number Information systems
of lines printed to 1. If there are two equal values, we do not get 3 62V014
architectures
5

the right result. 4 V035 Quality management 5


5 V274 Performance marketing 6
6 U0003 Roman law 8
7 U005 Substantive criminal law 262 8
8 0196 Systems theory 7

Databases

263

37
09/05/2025

HAVING
 After GROUP BY we can no longer add conditions to WHERE, so there is a solution called HAVING,
which is used only with GROUP BY and is designed to filter lists of groups. It works similarly to
WHERE, but it takes into account the groups in GROUP BY.

 List courses with more than 1 student enrolled.


SELECT course.id_c, course_name, COUNT(DISTINCT enrolment.FK_student) AS no_students
FROM course, enrolment
WHERE course.id_c = enrolment.FK_course
GROUP BY course.id_c
HAVING no_students > 1; Enrolment
year_of_enr
id_e grade FK_Student FK_Course
olment
Course
1 8 2026/2027 1 1
id_c course_code course_title ects_points 2 7 2026/2027 1 2
1 62V108 Databases I 5 3 9 2026/2027 2 4 Result
2 61V013 Computer networks 5 4 9 2026/2027 2 5 stevilo_studen
Information systems 5 NULL 2026/2027 3 1 id_c course_title ts
3 62V014 5
architectures 6 10 2026/2027 3 3 1 Databases I 3
4 V035 Quality management 5 7 6 2025/2026 4 6 Information systems
3 2
5 V274 Performance marketing 6 8 8 2025/2026 4 7 architectures
6 U0003 Roman law 8 9 NULL 2026/2027 1 NULL
7 U005 Substantive criminal law 8 10 9 2026/2027 2 1 264
8 0196 Systems theory 7 11 6 2026/2027 3 1
12 8 2026/2027 4 3

HAVING
 List the courses in which students received higher grades than the average of all grades.
SELECT course.id_c, course_title, MAX(grade) AS highest_grade
FROM course, enrolment
WHERE course.id_c = enrolment.FK_course
GROUP BY course.id_c
HAVING highest_grade >
(SELECT AVG(grade) FROM enrolment); Result
id_c course_title highest_grade
1 Databases I 9
3 Information systems architectures 10
Enrolment
4 Quality management 9
year_of_enr
id_e grade FK_Student FK_Course 5 Performance marketing 9
olment
Course
1 8 2026/2027 1 1
2 7 2026/2027 1 2 id_c course_code course_title ects_points
3 9 2026/2027 2 4 1 62V108 Databases I 5
4 9 2026/2027 2 5 2 61V013 Computer networks 5
5 NULL 2026/2027 3 1 Information systems
3 62V014 5
6 10 2026/2027 3 3 architectures
7 6 2025/2026 4 6 4 V035 Quality management 5
8 8 2025/2026 4 7 5 V274 Performance marketing 6
9 NULL 2026/2027 1 NULL 6 U0003 Roman law 8
10 9 2026/2027 2 1 7 U005 Substantive criminal law 8 265
11 6 2026/2027 3 1 8 0196 Systems theory 7
12 8 2026/2027 4 3

38
09/05/2025

HAVING
Result
name last_name average_grade
David Novak 7.5000

 Let's write out the student who received the highest Maja Krajnc 9.0000
Ales Novak 8.0000
average grade.
Maja Malič 7.3333
SELECT name, last_name, AVG(grade) as avg_grade
FROM enrolment
JOIN student ON enrolment.FK_student = student.id_s
GROUP BY FK_student
HAVING avg_grade = Result
MAX(avg_value)
(SELECT MAX(avg_value ) FROM
9.0000
(SELECT name, last_name, AVG(grade) as avg_value
Enrolment
year_of_en FK_Stu FK_Cou FROM enrolment
id_e grade
rolment dent rse
1 8 2026/2027 1 1
JOIN student ON enrolment.FK_student = student.id_s
2 7 2026/2027 1 2 GROUP BY FK_student)
3 9 2026/2027 2 4
4 9 2026/2027 2 5 highest_avg);
5 NULL 2026/2027 3 1 Result
6 10 2026/2027 3 3 student name last_name average_grade
7 6 2025/2026 4 6 last_nam Maja Krajnc 9.0000
8 8 2025/2026 4 7 id_s name enrolment_nr date_of_birth
e
9 NULL 2026/2027 1 NULL 1 David Novak E9320376041 12.12.2008
10 9 2026/2027 2 1 2 Maja Krajnc E3107410974 15.03.2008
11 6 2026/2027 3 1
3 Ales Novak E1234464687 NULL
12 8 2026/2027 4 3 266
4 Maja Malič E2137410974 15.05.2009

student
id_ nam last_ enrolme date_of_bi
s e name nt_nr rth
Davi Nova E932037 12.12.200

CREATE VIEW
1
d k 6041 8
Krajn E310741 15.03.200
2 Maja
c 0974 8
Nova E123446
 For queries that we run frequently, we can create a view that we call by 3 Ales
k 4687
NULL

the name we are referring to. Result 4 Maja Malič


E213741 15.05.200
0974 9
 Let's write out the student who received the highest average grade.
name last_name average_grade
David Novak 7.5000
DROP VIEW IF EXISTS average_grade_students; Maja Krajnc 9.0000 Enrolment
year_of_en FK_Stu FK_Cou
CREATE VIEW average_grade_students AS Ales Novak 8.0000 id_e grade
rolment dent rse
Maja Malič 7.3333 1 8 2026/2027 1 1
SELECT name, last_name, AVG(grade) as avg_grade 2 7 2026/2027 1 2
3 9 2026/2027 2 4
FROM enrolment 4 9 2026/2027 2 5
5 NULL 2026/2027 3 1
JOIN student ON enrolment.FK_student = student.id_s 6 10 2026/2027 3 3
Result 7 6 2025/2026 4 6
GROUP BY FK_student; MAX(avg_value) 8 8 2025/2026 4 7
9.0000 9 NULL 2026/2027 1 NULL
#SELECT * FROM average_grade_students ; 10 9 2026/2027 2 1
11 6 2026/2027 3 1
SELECT * 12 8 2026/2027 4 3

FROM average_grades_students
WHERE avg_grade = (SELECT MAX(avg_grade) Result
name last_name average_grade
FROM average_grade_students); Maja Krajnc 9.0000

267

39
09/05/2025

student

NULL
last_nam
id_s name enrolment_nr date_of_birth
e
1 David Novak E9320376041 12.12.2008
2 Maja Krajnc E3107410974 15.03.2008
3 Ales Novak E1234464687 NULL
• A NULL value is a cell where no value is entered. This is not equal to 0. 4 Maja Malič E2137410974 15.05.2009

• SELECT name, last_name, date_of_birth Result


FROM student name last_name date_of_birth
WHERE date_of_birth > '2008-12-12' David Novak 12.12.2008
OR date_of_birth <= '2008-12-12'; Maja Krajnc 15.03.2008
Even though it is always a correct statement (tautology), NULL isMaja
not included
Malič in the result!15.05.2009

• SELECT COUNT(date_of_birth)
FROM student;
Result
In this line counting, NULL is excluded!
3
• SELECT date_of_birth
Result
FROM student;
date_of_birth
However, in this line output, NULL is included.
12.12.2008
15.03.2008
NULL
15.05.2009

268

Nested queries
 They can be used in SELECT, INSERT, UPDATE, DELETE.
 There are:
 Unrelated nested queries
 The inner statement can be run independently of the outer statement, but is used to execute the outer
statement.
 The inner query is executed first and only once, and then the results are used for the outer phrase.
 They can appear in WHERE or FROM.
 Related nested queries
 An inner statement cannot be run on its own without an outer statement, because the inner statement uses the
data from the outer statement.
 The inner statement will be executed for each result of the outer statement.

269

40
09/05/2025

Unrelated nested queries


 In WHERE: list the students who received grades higher than 8.
SELECT name, last_name FROM student Result
WHERE id_s IN name last_name
(SELECT FK_student FROM enrolment Maja Krajnc
Ales Novak
WHERE grade > 8);
 V FROM: Print the minimum number of courses in which students are enrolled
SELECT MIN(nr_courses)
FROM
Result
(SELECT FK_student, COUNT(FK_course) as nr_courses Enrolment
2
FROM enrolment id_e grade
year_of_en FK_Stu FK_Cou
rolment dent rse
GROUP BY FK_student) nr_courses_per_student; 1 8 2026/2027 1 1
2 7 2026/2027 1 2
 It is mandatory to name the nested query in the above example. 3 9 2026/2027 2 4
4 9 2026/2027 2 5
5 NULL 2026/2027 3 1
student 6 10 2026/2027 3 3
7 6 2025/2026 4 6
last_nam
id_s name enrolment_nr date_of_birth 8 8 2025/2026 4 7
e
9 NULL 2026/2027 1 NULL
1 David Novak E9320376041 12.12.2008
10 9 2026/2027 2 1
2 Maja Krajnc E3107410974 15.03.2008 11 6 2703
2026/2027 1
3 Ales Novak E1234464687 NULL 12 8 2026/2027 4 3
4 Maja Malič E2137410974 15.05.2009

Related nested queries


 We want to see how many students are enrolled in which course.
Result
id_c course_title No_students
1 Databases I 4
SELECT id_c, course_title, 2 Computer networks 1
(SELECT COUNT(FK_student) FROM enrolment 3 Information systems architectures 2
4 Quality management 1
WHERE enrolment.FK_course=P.id_c) 5 Performance marketing 1
6 Roman law 1
FROM course P; 7 Substantive criminal law 1
8 Systems theory 0

Enrolment
year_of_en FK_Stu FK_Cou
id_e grade
rolment dent rse
1 8 2026/2027 1 1 Course
2 7 2026/2027 1 2 id_c course_code course_title ects_points
3 9 2026/2027 2 4
1 62V108 Databases I 5
4 9 2026/2027 2 5
2 61V013 Computer networks 5
5 NULL 2026/2027 3 1
Information systems
6 10 2026/2027 3 3 3 62V014 5
7 6 2025/2026 4 6
architectures
8 8 2025/2026 4 7 4 V035 Quality management 5
9 NULL 2026/2027 1 NULL 5 V274 Performance marketing 6
10 9 2026/2027 2 1 6 U0003 Roman law 8
11 6 2026/2027 3 1 7 U005 Substantive criminal law 8 271
12 8 2026/2027 4 3 8 0196 Systems theory 7

41
09/05/2025

TIMESTAMP / DATETIME
• An important difference between DATETIME and TIMESTAMP is that Some functions for date and time:
DATETIME stores the date and time values in the calendar and
clock on the server where the database is stored. TIMESTAMP, on  SELECT TIMESTAMPDIFF(SECOND,
the other hand, stores a specific point in time according to UTC date_from, date_to) as
(Coordinated Universal Time).
time_difference;
• TIMESTAMP is suitable for use e.g. when storing invoices in a
database where you have a chain of cafés in different time zones. If #time difference in seconds
a café in Athens (EET) would issue an invoice on 16.12.2020 at
10.30 local time, this is at 8.30 on the same day UTC. A café in
 SELECT DATEDIFF(date_from,
London (GMT) would invoice at 10.30 local time, so that's 10.30 on date_to) as datediff;
the same day UTC.
#difference in days
• The values for TIMESTAMP or DATETIME are automatically assigned
in case the data type is also assigned the DEFAULT  SELECT DATE(date_from),
CURRENT_TIMESTAMP constraint. TIME(date_from), YEAR(date_from);
• The difference between queries with DATETIME and TIMESTAMP is #select e.g. only the day from
that MySQL converts the TIMESTAMP values from the current time
zone to UTC and converts back from UTC to the current time zone DATETIME or only the time or year
in the query.

272

Trigger
SQL - DML, DQL

42
09/05/2025

Trigger
 A trigger is an SQL statement that is automatically fired on a specific event (insert,
update, delete) and executes the commands you define.
 With a trigger, you can avoid repetitive code.
 Examples:
 When updating the grades table, we want the new average grade to be automatically saved in
the students' average grades table.
 We want to send an email to every new user. When we add a new user, an email is
automatically sent.
 We want to keep track of when we have entered a row in the table (log).
 Display all triggers in the selected database: SHOW TRIGGERS FROM {
database_name };
 Delete selected trigger: DROP TRIGGER IF EXISTS { trigger_name };

Trigger
 Contents of the trigger:
DELIMITER $$ # mark a new delimiter between sentences so that the sentence ends at $$ instead of at ; in the trigger content
CREATE TRIGGER { name of the requestor }
time_prog { BEFORE | AFTER } # before or after the event
event_projector { INSERT | UPDATE | DELETE } # events can be insert, update or delete
ON { table_name } # this is the name of the table that the trigger is monitoring, not the table where the change will be
made
FOR EACH ROW # the trigger will be automatically triggered for each changed row
BEGIN # if the trigger consists of several commands, BEGIN and END are mandatory
content_projector with accesses to values
{ INSERT | UPDATE | DELETE | SELECT}
{ NEW | OLD }; Trigger
END $$ Trigger event Access to value
time
DELIMITER ; # set the separator between SQL statements INSERT NEW
back to ; BEFORE |
UPDATE OLD | NEW
AFTER
DELETE OLD

43
09/05/2025

Trigger before data insertion


• Changing text to upper case before inserting data.
CREATE TRIGGER course_by_large
BEFORE INSERT ON course
FOR EACH ROW
SET NEW.course_title = UPPER(NEW.course_title);

INSERT INTO course VALUES (NULL, '61V018', 'Application Development for Internet',
5);

Course
id_c course_code course_title ects_points
1 62V108 Databases I 5
2 61V013 Computer networks 5
Information systems
3 62V014 5
architectures
4 V035 Quality management 5
5 V274 Performance marketing 6
6 U0003 Roman law 8
7 U005 Substantive criminal law 8
DEVELOPING APPLICATIONS
8 61V018 5
FOR THE INTERNET 276

Trigger after data insertion


 The same seer:
• Change in the average grade at enrolment of the student's DELIMITER $$
new grade. CREATE TRIGGER average_grade_student
CREATE TRIGGER average_grade_student AFTER INSERT ON enrolment FOR EACH ROW
AFTER INSERT ON enrolment FOR EACH ROW BEGIN
UPDATE student with JOIN SELECT AVG(grade) INTO @average_grade FROM
enrolment
(SELECT FK_student, AVG(grade) AS
WHERE FK_student = NEW.FK_student;
average_grade
FROM enrolment GROUP BY FK_student) v
UPDATE student s
ON s.id_s=v.FK_student SET s.average_value = @average_value
SET s.average_value = v.average_value; WHERE id_s = NEW.FK_student;
END $$
DELIMITER ; Enrolment
year_of_enr
id_e grade FK_Student FK_Course
INSERT INTO enrolment (grade, olment
student 1 8 2026/2027 1 1
year_enrolled, FK_student, FK_course)
last_na average_gra 2 7 2026/2027 1 2
id_s name
me
enrolment_nr date_of_birth
de
VALUES (10, '2026/2027', 1, 5); 3 9 2026/2027 2 4
1 David Novak E9320376041 12.12.2008 7.50 8.33 4 9 2026/2027 2 5
2 Maja Krajnc E3107410974 15.03.2008 9.00 5 NULL 2026/2027 3 1
3 Ales Novak E1234464687 NULL 10.00 6 10 2026/2027 3 3
4 Maja Malič E2137410974 15.05.2009 7.00 7 6 2025/2026 4 2776
98 8
10 2025/2026
2026/2027 1 4 57

44
09/05/2025

Trigger after data update


• Keeping a history of changes in students' course grades.
DELIMITER $$
CREATE TRIGGER history_grade
AFTER UPDATE ON ENTRY FOR EACH ROW
BEGIN
INSERT INTO grades VALUES
(NULL, NOW(), OLD.id_e, OLD.FK_course, OLD.FK_student, OLD.grade, NEW.grade);
END$$
DELIMITER ;

UPDATE enrolment SET grade=7 WHERE id_e=5;

Enrolment
year_of_enrol
id_e grade FK_Student FK_Course
ment
1 8 2026/2027 1 1 Course_grades
2 7 2026/2027 1 2 ID_grade_pri
Date_change id_e id_c id_s grade_before grade_after
3 9 2026/2027 2 4 or
4 9 7 2026/2027 2 5 2021-01-06
1 5 1 3 NULL 7
5 NULL 2026/2027 3 1 11:15:00
6 10 2026/2027 3 3
7 6 2025/2026 4 6 278
8 8 2025/2026 4 7

SQL - TCL

45
09/05/2025

Transactions
• TCL - commands intended for transactions within a DB
• Transactions are composite operations that are executed on the DBMS and
must be executed in full or no operation is executed.
• Transactions ensure that the data in the system is consistent and allow for
proper recovery even in the event of errors (e.g. system failure, power loss).
• If a system error occurs during the execution of a transaction, a rollback to the
state before the transaction was executed must be performed.

 Example:
 We want to transfer money from one smart wallet to another. Several things happen
when we do this (decrease the amount on one wallet and increase the amount on the
other). First, the amount on the first wallet is reduced. Then we realise that the second
wallet we are transferring to does not exist. At that point, the whole transaction is
reversed (rollback), i.e. the money is refunded back to the first wallet. 280

Transaction properties
• Transactions must follow the ACID (Atomicity, Consistency, Isolation, Duration) rule set to
ensure data validity despite errors, power loss, etc.
• Atomicity
• All statements (e.g. multiple inserts, updates, selects) in a transaction are executed or none are
executed (rollback). All-or-none approach.
• Consistency
• The data must be consistent and must not leave the database in an inconsistent state after the
transaction. Business rules (constraints, links) must be respected.
• Isolation / Insulation
• Transactions have no effect on each other during the duration (tables or rows are locked at the
beginning and unlocked at the end - lock/unlock table).
• Durability / Duration
• Changes on successful transactions will be saved (despite e.g. loss of electricity, etc.). All activities
will be recorded (in logs).

281

46
09/05/2025

Transaction (Transaction)
 Transaction start: SAVEPOINT;
 End of transaction: COMMIT;
 If an error occurred between the start and end of the transaction, no data will be entered. You can also abort
the transaction yourself with the ROLLBACK command.
 The content of the transaction:
START TRANSACTION ; #start transaction
Property_transactions: { WITH CONSISTENT SNAPSHOT | READ WRITE | READ ONLY }
#we can enter multiple SQL statements
BEGIN
COMMIT ; #transaction is executed and changes are saved
ROLLBACK ; #data is reverted to the original state for the current transaction
SET autocommit = {0 | 1} #if nothing is selected, 1 is selected in MySQL, which is the same as if START
TRANSACTION is at the beginning and COMMIT is at the end. In this case, we cannot use ROLLBACK to
discard the changes unless an error occurs during execution.

Example of a transaction
• Keeping the average grade of students.
START TRANSACTION;
SELECT @average_grade:= AVG(grade)
FROM enrolment
WHERE FK_student =2;
UPDATE student
SET average_grade = @average_grade
WHERE id_s=2;
SELECT * FROM student;
COMMIT;

student
last_na average_gra
id_s name enrolment_nr date_of_birth
me de
1 David Novak E9320376041 12.12.2008 NULL
2 Maja Krajnc E3107410974 15.03.2008 NULL 9.00
3 Ales Novak E1234464687 NULL NULL
4 Maja Malič E2137410974 15.05.2009 NULL 283

47
09/05/2025

Example of a transaction
• Entering a new item and cancelling a transaction.
START TRANSACTION;
SELECT @course_id:= MAX(id_c)+1
FROM course;

INSERT INTO course


VALUES (@course_id,'61V015','User interfaces',5);

ROLLBACK;

Course
id_c course_code course_title ects_points
1 62V108 Databases I 5
2 61V013 Computer networks 5
Information systems
3 62V014 5
architectures
4 V035 Quality management 5
5 V274 Performance marketing 6
6 U0003 Roman law 8
7 U005 Substantive criminal law 8
8 61V015 User interfaces 5
284

Database management

48
09/05/2025

Index / INDEX
• An index is a data structure that improves the efficiency of data search operations. It is a
collection of key-value pairs that allows the database to quickly find specific rows in a table.
• We often use indexes in columns, which are often used in WHERE statements.
• Using indexes can slow down the updating of the data in the table because the indexes must
also be updated. So use index only where you will be doing frequent lookups.
• For PRIMARY KEY and UNIQUE, the index is already automatically created.

• Example of adding an index to make it faster to look at the email column:


ALTER TABLE student
ADD INDEX ( email ) USING BTREE;

286

Stored Procedures / STORED PROCEDURES


• Stored procedures are predefined SQL statements that are stored in the
database itself. Procedures are designed to contain specific tasks or
operations, allowing them to be executed and re-executed without having to
rewrite the underlying SQL code.
• When we need to execute the same SQL statements multiple times, we save
the process and save development time. An example application is data
analytics, where we run e.g. daily reporting.

287

49
09/05/2025

Example of a stored procedure


• Calculate the average grade for a student with id=3.
DELIMITER $$
CREATE PROCEDURE get_student_preliminary_grade(IN id INT)
BEGIN
SELECT id_s, name, last_name, AVG(grade) as avg_grade
FROM enrolment
JOIN student ON enrolment.FK_student = student.id_s Result
id_s name last_name average_grade
WHERE id_s = id 3 Ales Novak 8.0000
GROUP BY FK_student;
END $$
DELIMITER ;

CALL get_average_student_grade(3);

DROP PROCEDURE get_average_student_grade;

288

Events / EVENTS
• Events execute a specific SQL statement at a predefined time or interval.
They can be used to automate repetitive tasks such as performing data
backups, sending email notifications or updating statistics. They can also be
used to call stored procedures.

289

50
09/05/2025

Example of an event
• Calling a stored procedure
DELIMITER $$
CREATE EVENT IF NOT EXISTS execute_procedure
ON SCHEDULE AT current_timestamp
# ON SCHEDULE EVERY 15 second #there are more options
DO
BEGIN Result
id_s name last_name average_grade
CALL get_student_overall_assessment(3); 3 Ales Novak 8.0000
END $$
DELIMITER ;

DROP EVENT execute_procedure;

290

291

51
09/05/2025

Other information about


databases

Database administration
 Data Administrator (DA) • Database Administrator (DBA)
 Designs the database (defines the content • Supervised by
and structure of the database) • Implements short-term objectives (daily
 Pledge long-term goals operations)
 Defines standards • Has the technical know-how
• Specialised for a specific DBMS
 Good at leadership and management

293

52
09/05/2025

Syntax differences in different DBMSs


• ANSI (1986), ISO (1987).
• The SQL language works according to a
standard, but there are differences
between different systems.
• The most common DBMSs are:
• MySQL, Oracle, MS SQL, PostgreSQL,
SQLite,...
• Differences occur in data types, use of
quotation marks, different reserved
words,...

294

Some differences in syntax between different DBMSs

AUTO INCREMENT id AUTO_INCREMENT id NUMBER Id IDENTITY(1,1) Id SERIAL id AUTOINCREMENT


GENERATED ALWAYS
as IDENTITY(START
with 1 INCREMENT by
1)

Intersection / INTERSECT INTERSECT INTERSECT INTERSECT


Except / MINUS EXCEPT EXCEPT EXCEPT
Error for incorrect Depends on the Do not let SQL run Do not let SQL run Do not let SQL run It would start, but the
SQL settings on the MySQL because it is not because it is not because it is not result would be wrong.
(SELECT name, server (on certain grouped by the year of grouped yet by the year grouped by the year of
last_name, versions it will start enrolment. (It is more of the enrolment. (It is enrolment. (It is more
COUNT(id_c), without error). standard). / ORA- more like the standard) / ERROR:
year_of_enrolment -...- 00979: not a GROUP standard). / Column column "xy" must
GROUP BY id_s;) BY expression 'xy' is invalid in the appear in the GROUP
select list because it is BY clause or be used in
not contained in either an aggregate function
an aggregate function
or the GROUP BY
clause.
295
Documentation MySQL Oracle MS SQL PostgreSQL SQLite

53
09/05/2025

Restoring the database


• We need to ensure that the database can be restored in
the event of a failure/attack:
• Creating a mechanism to regularly create copies of the
database (e.g. master-slave replication of the database).
• Creation of logs that record all changes to the database.
• A checkpoint service that allows the database to be
periodically checked and reverted to the previous state of the
validated control.
• Recovery management that restores the system back to its
pre-failure state.

296

After construction of the DB


• Maintenance, updating
• The possibility to use
and copy existing
databases and to
customise them
• Interfacing with other
programming
languages
• E.g. with PHP and
MySQLi drivers
• $mysqli = new
mysqli("server/IP", "user",
"password", "database");

297

54
09/05/2025

SQL injection
• SQL injection is a vulnerability in a dynamic web application
where an attacker can modify SQL statements in a database
management application. An attacker can obtain data from
other users or other data to which the application has access.
An attacker can also delete or modify data.

298

SQL injection
• Example of PHP code that checks user information:
<?php
$selected_user = $_GET['user_name'];
$sql = "SELECT username, password FROM users" .
"WHERE user_name='$selected_user'";
$rs = $db->executeQuery($sql); ?>

299

55
09/05/2025

SQL injection

300

SQL injection

301

56
09/05/2025

SQL injection
• Solutions to avoid this:
• Pre-prepared SQL statements
• Software code overview
• PHP instance of PHP DataObjects (PDO):
• $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
• $stmt->execute([ 'name' => $name ]);
• foreach ($stmt as $row) {
• // Do something with $row
• }

302

Databases

57

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy