mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-07-27 21:29:09 +02:00
[DMDB] SQL basics completed
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 261 KiB |
@@ -0,0 +1,16 @@
|
||||
SELECT MAX(price) as MAX_PRICE FROM Products; -- Get the most expensive product
|
||||
SELECT AVG(grade) as AVG_GRADE FROM Exams WHERE id = 0; -- Get the average grade for an exam
|
||||
|
||||
-- Aggregation with grouping (Remember, only aggregates and cols in GROUP BY clause can
|
||||
-- appear in SELECT clause!)
|
||||
SELECT id, AVG(grade) as "Average Grade", COUNT(grade) as "Count"
|
||||
FROM ExamResults GROUP BY id; -- Average grade for each exam and number of students taking it
|
||||
|
||||
SELECT id, AVG(grade) as avg, COUNT(grade) as cnt FROM ExamResults
|
||||
GROUP BY id HAVING cnt > 0 ORDER BY avg DESC LIMIT 20;
|
||||
|
||||
-- Get exam details for all exams as filtered before
|
||||
SELECT * FROM (
|
||||
SELECT id, AVG(grade) as avg, COUNT(grade) as cnt FROM ExamResults
|
||||
GROUP BY id HAVING cnt > 0 ORDER BY avg DESC LIMIT 20
|
||||
) as filtered JOIN Exams e ON filtered.id = e.id;
|
||||
Binary file not shown.
@@ -22,28 +22,28 @@
|
||||
|
||||
\vspace{1cm}
|
||||
\begin{center}
|
||||
\includegraphics[width=0.5\linewidth]{~/projects/latex/assets/logo.jpg}
|
||||
\includegraphics[width=0.5\linewidth]{~/projects/latex/assets/logo.jpg}
|
||||
\end{center}
|
||||
|
||||
|
||||
\vspace{2cm}
|
||||
\begin{center}
|
||||
\begin{Large}
|
||||
\quote{A curry can be written in many different ways}
|
||||
\end{Large}
|
||||
\begin{Large}
|
||||
\quote{A curry can be written in many different ways}
|
||||
\end{Large}
|
||||
|
||||
\hspace{3cm} - Prof. Dr. Gustavo Alonso, 2026
|
||||
\hspace{3cm} - Prof. Dr. Gustavo Alonso, 2026
|
||||
\end{center}
|
||||
|
||||
\vspace{1.5cm}
|
||||
\begin{center}
|
||||
FS2026, ETHZ
|
||||
FS2026, ETHZ
|
||||
|
||||
\begin{Large}
|
||||
Summary of the Lecture Slides
|
||||
\end{Large}
|
||||
\begin{Large}
|
||||
Summary of the Lecture Slides
|
||||
\end{Large}
|
||||
|
||||
\url{https://systems.ethz.ch/education/courses/2026-spring/dmdb.html}
|
||||
\url{https://systems.ethz.ch/education/courses/2026-spring/dmdb.html}
|
||||
\end{center}
|
||||
|
||||
\newpage
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
\newglossaryentry{declarative}{
|
||||
name={declarative},
|
||||
description={Describes \textit{what} to achieve, but not how}
|
||||
name={declarative},
|
||||
description={Describes \textit{what} to achieve, but not how}
|
||||
}
|
||||
\newglossaryentry{imperative}{
|
||||
name={imperative},
|
||||
description={Describes how to achieve something}
|
||||
name={imperative},
|
||||
description={Describes how to achieve something}
|
||||
}
|
||||
\newglossaryentry{record}{
|
||||
name={record},
|
||||
description={}
|
||||
name={record},
|
||||
description={}
|
||||
}
|
||||
\newglossaryentry{schema}{
|
||||
name={schema},
|
||||
description={A set of relations}
|
||||
name={schema},
|
||||
description={A set of relations}
|
||||
}
|
||||
\newglossaryentry{bag}{
|
||||
name={bag},
|
||||
description={A bag, or multiset, is a set, in which, (as is usual with sets) order does not matter, but duplicates are allowed}
|
||||
}
|
||||
\newglossaryentry{subquery}{
|
||||
name={subquery},
|
||||
description={Also Nested Query, a separate query that can be used in the \texttt{FROM} or \texttt{WHERE} clause of another query. See \ref{sec:nested-queries}}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,18 @@ The DDL is used to describe the schema of relations, in \sql\ called tables.
|
||||
For that, we provide a table name, the columns and their data types.
|
||||
|
||||
\sql\ supports the following data types (plus more):
|
||||
\begin{multicols}{2}
|
||||
\begin{itemize}[itemsep=-2pt]
|
||||
\item \texttt{char(n)}
|
||||
\item \texttt{varchar(n)}
|
||||
\item \texttt{integer}
|
||||
\item \texttt{blob} or \texttt{raw} (for large binaries)
|
||||
\item \texttt{date}
|
||||
\end{itemize}
|
||||
\begin{multicols}{3}
|
||||
\begin{itemize}[itemsep=-2pt]
|
||||
\item \texttt{CHAR(n)}
|
||||
\item \texttt{VARCHAR(n)}
|
||||
\item \texttt{INT}
|
||||
\item \texttt{BIGINT}
|
||||
\item \texttt{SMALLINT}
|
||||
\item \texttt{FLOAT}
|
||||
\item \texttt{BLOB(n)} (for large binaries)
|
||||
\item \texttt{DATETIME}
|
||||
\item \texttt{MONEY}
|
||||
\end{itemize}
|
||||
\end{multicols}
|
||||
|
||||
|
||||
@@ -18,7 +22,8 @@ For that, we provide a table name, the columns and their data types.
|
||||
Use the DDL \texttt{CREATE TABLE} keyword to create a table. We can set default values for certain attributes,
|
||||
or can add constraints to them.
|
||||
|
||||
% TODO: Constraints (such as NOT NULL)
|
||||
Since the primary key must be unique for each entry, it may be useful to configure the primary key attribute with the following constraints
|
||||
\texttt{PrimaryKeyField INT NOT NULL AUTO\_INCREMENT}
|
||||
|
||||
\inputcodewithfilename{sql}{}{code/sql/ddl/create.sql}
|
||||
|
||||
@@ -34,3 +39,28 @@ Be aware that if we ADD a column to the schema, unless a default value is provid
|
||||
\subsubsection{Deleting Tables}
|
||||
|
||||
\inputcodewithfilename{sql}{}{code/sql/ddl/delete.sql}
|
||||
|
||||
|
||||
\subsubsection{Constraints}
|
||||
\sql\ supports a number of constraints that can be put on the different attributes of a schema.
|
||||
\begin{itemize}
|
||||
\item \texttt{NOT NULL}: Disallows this column to be set to \texttt{NULL}, or have a \texttt{NULL} value
|
||||
\item \texttt{UNIQUE}: The value of each value in this column must be unique, but it can be \texttt{NULL}.
|
||||
An arbitrary number of columns can have \texttt{NULL} and still be valid
|
||||
\item \texttt{PRIMARY KEY}: Sets this column as the primary key. \texttt{NOT NULL} and \texttt{UNIQUE} is set on it implicitly.
|
||||
Contrary to common intuition, it can be set on multiple columns.
|
||||
\item \texttt{CHECK c}: Check that the values fulfil a condition.
|
||||
This condition has the same syntax as for the \texttt{WHERE} clause (see \ref{sec:sql-basic-ops})
|
||||
\item \texttt{REFERENCES table}: A Foreign Key, used to refer to another tuple from a different relation.
|
||||
It is typically referencing the primary key of the other table.
|
||||
\end{itemize}
|
||||
For \texttt{REFERENCES}, there are many options for maintenance, which can be set on creating a reference:
|
||||
\begin{itemize}
|
||||
\item \bi{Cascade}: Propagate \texttt{UPDATE} and \texttt{DELETE}
|
||||
\item \bi{Restrict}: Prevent deletion of the primary key before the change, causes error
|
||||
\item \bi{No Action}: Prevent modifications after attempting change, causes error
|
||||
\item \bi{Set default, Set Default}: Set references to \texttt{NULL} or default value
|
||||
\end{itemize}
|
||||
|
||||
\inlineexample
|
||||
\mint{sql}|CREATE TABLE tab (id integer REFERENCES OtherTable ON DELETE cascade ON UPDATE cascade)|
|
||||
|
||||
@@ -7,16 +7,23 @@ To rename, we can set \texttt{I = Column as Name, Column2 as Name2}, etc
|
||||
|
||||
% TODO: Make RA an acronym, too
|
||||
\inlinetheorem Every SPJR RA expression can be written in \texttt{SELECT ... FROM ... WHERE ...} form:
|
||||
\begin{tables}{lll}{Operation & Notation & SQL}
|
||||
Selection & $\sigma_c(R)$ & \texttt{SELECT * FROM R WHERE c;} \\
|
||||
Projection & $\Pi_{A_1, \ldots, A_n} R$ & \texttt{SELECT A1, \ldots, An FROM R;} \\
|
||||
Cartesian Product & $R_1 \times R_2$ & \texttt{SELECT * FROM (R1, R2);} \\
|
||||
Rename & $\rho_{a, b, c} R$ & \texttt{SELECT A as a, \ldots, B as c FROM R;} \\
|
||||
Union & $R_1 \cup R_2$ & \texttt{R1 UNION R2;} \\
|
||||
Difference & $R_1 - R_2$ & \texttt{R1 EXCEPT R2;} \\
|
||||
Intersection & $R_1 - R_2$ & \texttt{R1 INTERSECT R2;} \\
|
||||
\begin{tables}{lll}{Operation & Notation & SQL}
|
||||
Selection & $\sigma_c(R)$ & \texttt{SELECT * FROM R WHERE c;} \\
|
||||
Projection & $\Pi_{A_1, \ldots, A_n} R$ & \texttt{SELECT A1, \ldots, An FROM R;} \\
|
||||
Cartesian Product & $R_1 \times R_2$ & \texttt{SELECT * FROM (R1, R2);} \\
|
||||
Rename & $\rho_{a, b, c} R$ & \texttt{SELECT A as a, \ldots, B as c FROM R;} \\
|
||||
Union & $R_1 \cup R_2$ & \texttt{R1 UNION R2;} \\
|
||||
Difference & $R_1 - R_2$ & \texttt{R1 EXCEPT R2;} \\
|
||||
Intersection & $R_1 - R_2$ & \texttt{R1 INTERSECT R2;} \\
|
||||
\end{tables}
|
||||
Since \sql\ implements bag and not set semantics, there is a \texttt{DISTINCT} keyword, which is used to remove duplicates.
|
||||
|
||||
For the last three operations, \texttt{R1} and \texttt{R2} typically are other \sql\ statements:
|
||||
Since \sql\ implements \gls{bag} and not set semantics, there is a \texttt{DISTINCT} keyword, which is used to remove duplicates.
|
||||
It is to be applied in the \texttt{SELECT} clause (\texttt{I} above), e.g.
|
||||
\mint{sql}|SELECT DISTINCT name FROM Data;|
|
||||
|
||||
For the last three operations, \texttt{R1} and \texttt{R2} typically are other \sql\ statements, example:
|
||||
\mint{sql}|(SELECT name FROM FirstTable) UNION (SELECT name FROM SecondTable)|
|
||||
In addition, to apply \textit{bag semantics}, as opposed to \textit{set semantics} append \texttt{ALL} to the expression (e.g. \texttt{UNION ALL})
|
||||
|
||||
We can also name the tables, e.g. $\texttt{T} = \texttt{One o, Two t}$, and then access columns from a specific table using
|
||||
$\texttt{I} = \texttt{o.Col, b.Col}$, or the like.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
\newpage
|
||||
\subsubsection{Basic operators}
|
||||
\label{sec:sql-basic-ops}
|
||||
\paragraph{Logical Operators}
|
||||
The following \sql\ logical operators are available (may not be exhaustive for all systems, \texttt{cop} is a comparison operator):
|
||||
\begin{tables}{p{4.5cm}p{12cm}}{Operator & Description}
|
||||
\texttt{P1 AND P2} & TRUE if \texttt{P1} and \texttt{P2} both are true \\
|
||||
\texttt{P1 OR P2} & TRUE if one of \texttt{P1} or \texttt{P2}, or both are true \\
|
||||
\texttt{C cop ALL query} & TRUE if all values \texttt{x} returned in \gls{subquery}\ \texttt{query} fulfil \texttt{C cop x} \\
|
||||
\texttt{C cop ANY query} & TRUE if one (or more) values \texttt{x} returned in \gls{subquery}\ \texttt{query} fulfil \texttt{C cop x}.
|
||||
\texttt{SOME} is logically equivalent \\
|
||||
\texttt{C BETWEEN low AND high} & TRUE if numerical, text or date value of \texttt{C} is between \texttt{low} and \texttt{high}. Both ends inclusive, negatable \\
|
||||
\texttt{C IN list} & TRUE if value of \texttt{C} is in the provided \texttt{list}.
|
||||
List format: \texttt{(val, val2)}. List can also be a \gls{subquery}, negatable \\
|
||||
\texttt{C LIKE R} & TRUE if value of \texttt{C} matches regex-like pattern \texttt{R}.
|
||||
(\% matches any number of chars, \_ matches a single, arbitray character) \\
|
||||
\texttt{EXISTS query} & TRUE if \gls{subquery}\ \texttt{query} retuns at least one row \\
|
||||
% \texttt{IN} & TRUE if \\
|
||||
\end{tables}
|
||||
|
||||
|
||||
\paragraph{Comparison \& Arithmetic Operators}
|
||||
\shade{gray}{Comparison Operators} $<, <=, =, >=, >$ are defined as usually, $<>$ is defined as not equal.
|
||||
|
||||
\shade{gray}{Arithmetic Operators} $+, -, *, /, \%$ are defined as usual.
|
||||
|
||||
We can use the arithmetic operators like this:
|
||||
\mint{sql}|SELECT Value * 1.1 FROM Data;|
|
||||
or in \texttt{WHERE} clauses like this:
|
||||
\mint{sql}|SELECT Value FROM (Data a, Data b) WHERE a.Value = b.Value - 1;|
|
||||
|
||||
\inlineremark You may have noticed that in the above query, the same table was used twice.
|
||||
This is referred to as a \bi{Self-Join} and can come in handy when comparing values in a single table.
|
||||
@@ -0,0 +1,39 @@
|
||||
\newpage
|
||||
\subsubsection{Join}
|
||||
Specifying two (or more) tables in the \texttt{FROM} clause will perform a cartesian product, e.g.
|
||||
\mint{sql}|SELECT * FROM (Table1, Table2);|
|
||||
returns all rows of the tables, next to each other.
|
||||
|
||||
Here, naming the tables in the \texttt{FROM} clause may come in handy, to not write out the entire name of the tables:
|
||||
\mint{sql}|SELECT * FROM (Table1 t, Table2 s) WHERE t.id = s.id;|
|
||||
\mint{sql}|SELECT * FROM (Table1, Table2) WHERE Table1.id = Table2.id;|
|
||||
Both of the above statements produce the same result.
|
||||
|
||||
|
||||
\paragraph{Nested Queries}
|
||||
\label{sec:nested-queries}
|
||||
To not have the cartesian product executed in the \texttt{FROM} clause, or to get a much more complex starting table, we can use a \gls{subquery}.
|
||||
These are parenthesized normal SQL queries.
|
||||
|
||||
We can create an alias for them using an \texttt{AS name} clause after the parenthesis as follows
|
||||
\mint{sql}|SELECT r.name FROM (SELECT * FROM Table) AS r;|
|
||||
or alternatively, using a \texttt{WITH} clause (replace the dummy queries with real queries):
|
||||
\mint{sql}|WITH CteName (SELECT * FROM Table) SELECT name FROM CteName;|
|
||||
|
||||
|
||||
\paragraph{Join Operations}
|
||||
If we don't specify the kind of join, an \texttt{INNER JOIN} is executed. The following three queries are equivalent
|
||||
\mint{sql}|SELECT * FROM Student, Tests WHERE Student.PersNr = Tests.PersNr;|
|
||||
\mint{sql}|SELECT * FROM Student JOIN Tests ON Student.PersNr = Tests.PersNr;|
|
||||
\mint{sql}|SELECT * FROM Student JOIN Tests USING (PersNr);|
|
||||
For the latter of the three, the parenthesis around the column are important, as omitting them is invalid syntax.
|
||||
|
||||
Other types of \texttt{JOIN} are:
|
||||
\begin{itemize}
|
||||
\item \texttt{NATURAL JOIN} (no \texttt{ON} required), joins on columns with same name
|
||||
\item \texttt{LEFT/RIGHT/FULL OUTER JOIN} (requires \texttt{ON}), also returns non-matching rows from left, right or both sides, respectively
|
||||
\end{itemize}
|
||||
|
||||
\begin{center}
|
||||
\includegraphics[width=0.5\textwidth]{assets/join-types.png}
|
||||
\end{center}
|
||||
@@ -0,0 +1,41 @@
|
||||
\newpage
|
||||
\subsubsection{Aggregations, Grouping, Sorting}
|
||||
\paragraph{Aggregations}
|
||||
\sql\ supports (at least) the aggregation functions \texttt{SUM}, \texttt{MIN}, \texttt{MAX}, \texttt{AVG}, \texttt{COUNT},
|
||||
whose output should be evident.
|
||||
|
||||
Please note that you cannot use the aggregation functions and still output another column,
|
||||
as they produce a single value.
|
||||
|
||||
For each of the functions, you can optionally specify \texttt{DISTINCT}.
|
||||
|
||||
We typically want to specify an \texttt{AS} clause, to make the output nicer to read
|
||||
|
||||
|
||||
\paragraph{Grouping}
|
||||
Grouping is used to, well, group together the outputs on a column.
|
||||
Using SQL, this is achieved using the \texttt{GROUP BY} clause.
|
||||
We specify the columns on which the grouping should occur.
|
||||
|
||||
\hl{\textbf{\textit{IMPORTANT}}} We can only use aggregates and columns appearing in the \texttt{GROUP BY} clause in the \texttt{SELECT} clause.
|
||||
|
||||
Using a \texttt{JOIN} function, it is of course then possible to go back retrieve the other columns.
|
||||
|
||||
To apply filtering on the columns, the \texttt{HAVING} clause can be used.
|
||||
It applies a comparison to a grouping column or an aggregate as specified in the \texttt{SELECT} clause:
|
||||
\mint{sql}|SELECT COUNT(name) as cnt FROM Students GROUP BY Department HAVING cnt > 1;|
|
||||
|
||||
|
||||
\paragraph{Sorting}
|
||||
We can sort the output of any query using the \texttt{ORDER BY column DIRECTION} clause, where \texttt{DIRECTION} is to be replaced with \texttt{ASC} or \texttt{DESC}:
|
||||
\mint{sql}|SELECT name FROM Students ORDER BY name DESC;|
|
||||
|
||||
|
||||
\paragraph{Limit}
|
||||
We can limit the number of columns to return using the \texttt{LIMIT} clause. Example:
|
||||
\mint{sql}|SELECT * FROM Exams LIMIT 10;|
|
||||
|
||||
|
||||
\paragraph{Example}
|
||||
Below some examples of \sql\ Queries using grouping, aggregations, sorting and grouping
|
||||
\inputcodewithfilename{sql}{}{code/sql/aggregations.sql}
|
||||
@@ -0,0 +1,21 @@
|
||||
\newpage
|
||||
\subsubsection{Null}
|
||||
\label{sec:sql-null}
|
||||
Whenever we have incomplete information, we can set a column to be \texttt{NULL}.
|
||||
If you have a column that has \texttt{NULL} values, when using \texttt{WHERE} clauses, these values are skipped.
|
||||
\textit{However} if you are not filtering on the column, a \texttt{NULL} value is returned.
|
||||
|
||||
To check if a column is \texttt{NULL}, you can use the \texttt{IS} keyword:
|
||||
\mint{sql}|SELECT * FROM Data WHERE name IS NULL|
|
||||
|
||||
\begin{itemize}[itemsep=-3pt]
|
||||
\item In \texttt{GROUP BY}, all \texttt{NULL}s form a single group.
|
||||
\item \texttt{COUNT(*)}, also counts rows with \texttt{NULL}
|
||||
\item \texttt{COUNT(TheColWithNull)} ignores rows with \texttt{NULL}
|
||||
\item Most other aggregations ignore \texttt{NULL}
|
||||
\item If all rows in an aggregations are \texttt{NULL}, so is the result
|
||||
\end{itemize}
|
||||
|
||||
The \texttt{OUTER JOIN} operators may (and likely will) introduce \texttt{NULL}
|
||||
|
||||
% TODO: Schema concepts? (slides 05, P20ff)
|
||||
@@ -0,0 +1,23 @@
|
||||
\subsubsection{Views}
|
||||
Views are a useful way of abstracting a complex query and is the result of a stored query.
|
||||
|
||||
We can create views using the following template:
|
||||
\mint{sql}|CREATE VIEW name AS query;|
|
||||
|
||||
We can then operate on it as if it were a table.
|
||||
|
||||
Common applications for views are privacy / access control, because you can limit access to tables only via certain views for every user;
|
||||
Usability is also often much better due to having less complex queries to write - you are just writing them once.
|
||||
|
||||
\shade{orange}{How a view is evaluated}
|
||||
This is quite simple in essence, the \texttt{VIEW}'s query is inserted into the query using the view.
|
||||
It then is then optimized as it normally would be, too. Of course, it is likely that more optimization can and has to be done on views.
|
||||
|
||||
|
||||
\paragraph{Updatable Views}
|
||||
Updating Views refers to updating values of the tables in the views.
|
||||
This is not straight forward and thus, many restrictions are placed on what kind of views are considered updatable.
|
||||
|
||||
In \sql, a view is updatable if and only if it involves \bi{one} base relation and its key, it does \bi{not} involve aggregates, groups or duplicate elimination.
|
||||
|
||||
In short, if there is one-to-one mapping between the view and base relation, it is updatable.
|
||||
@@ -4,6 +4,12 @@
|
||||
\input{parts/01_sql/01_ddl.tex}
|
||||
\input{parts/01_sql/02_dml.tex}
|
||||
\input{parts/01_sql/03_query-language/00_intro.tex}
|
||||
\input{parts/01_sql/03_query-language/01_basic-operators.tex}
|
||||
\input{parts/01_sql/03_query-language/02_join.tex}
|
||||
\input{parts/01_sql/03_query-language/03_aggregation.tex}
|
||||
\input{parts/01_sql/03_query-language/04_nulls.tex}
|
||||
\input{parts/01_sql/03_query-language/05_views.tex}
|
||||
% \input{parts/01_sql/03_query-language/}
|
||||
|
||||
\input{parts/01_sql/01_operations.tex}
|
||||
% \input{parts/01_sql/01_operations.tex}
|
||||
% \input{parts/01_sql/}
|
||||
|
||||
Reference in New Issue
Block a user