Databases I - 04 SQL-DQL,other
Databases I - 04 SQL-DQL,other
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
3
09/05/2025
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
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
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
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
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
10
09/05/2025
Comparative operator BETWEEN ... AND ... / NOT BETWEEN ... AND ...
• GREATEST(value1,value2)
• It chooses the highest of the given values. Result
SELECT GREATEST(5, 6, 7); GREATEST
7
210
11
09/05/2025
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
12
09/05/2025
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
• 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
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
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
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
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
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
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
224
18
09/05/2025
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
21
09/05/2025
232
22
09/05/2025
234
23
09/05/2025
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
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
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
27
09/05/2025
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
• 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
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
30
09/05/2025
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
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
• 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
36
09/05/2025
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.
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
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 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
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
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
44
09/05/2025
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;
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.
286
287
49
09/05/2025
CALL get_average_student_grade(3);
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 ;
290
291
51
09/05/2025
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
294
53
09/05/2025
296
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