Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.
Merged
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
39ce3d1
Added favicon to assets
shorodilov Nov 24, 2022
69cede0
Updated dependencies
shorodilov Nov 24, 2022
f6f393f
Updated project dependencies list
shorodilov Jan 28, 2023
2907c50
Added problem sets
shorodilov Jan 28, 2023
f9abecb
Updated Sphinx configuration
shorodilov Jan 28, 2023
5081108
Added bibliography
shorodilov Jan 28, 2023
780c735
Introduction to Python (#28)
shorodilov Jan 29, 2023
1236535
Moved images to "assets"
shorodilov Jan 29, 2023
2771c8f
fix Django initial lectures
vladyslavPonomaryovInBev Jan 21, 2023
433ec09
Add details how to push HWs
vladyslavPonomaryovInBev Jan 26, 2023
e748688
Added 'make all' instruction (target)
shorodilov Jan 29, 2023
2c556fb
Added appx.: userful software list
shorodilov Feb 4, 2023
2421ebf
Added docker to software list appx
shorodilov Feb 18, 2023
d95c3a3
Minor change - updated appxs headings
shorodilov Mar 12, 2023
f30d64f
Added operator precedence appendix
shorodilov Mar 12, 2023
98d86d2
Added string formating appendix
shorodilov Mar 13, 2023
120e1aa
Added appendecies files to Sphinx builder config
shorodilov Mar 13, 2023
2b0b981
Completed variables document
shorodilov Mar 12, 2023
5360ef0
Added syntax document
shorodilov Mar 12, 2023
db3d149
Updated data types overview
shorodilov Mar 12, 2023
028224c
Updated strings: indexes, slices, immutable
shorodilov Mar 12, 2023
e160272
Added string operations
shorodilov Mar 12, 2023
2ea10d6
Rebased 'feature/basics' onto 'devel' branch
shorodilov Mar 13, 2023
fb1c218
Added general sequence types description and operations
shorodilov Mar 12, 2023
7d945ac
Updated numeric types with values comparison section
shorodilov Mar 12, 2023
fcb9b41
Updated sequences types with value comparison section
shorodilov Mar 12, 2023
3cc83ba
Updated sets types with values comparison section
shorodilov Mar 12, 2023
4e38fd5
Minor changes in subsection headings
shorodilov Mar 12, 2023
3ab42da
Updated mapping type with value comparison section
shorodilov Mar 12, 2023
57f4267
Update string type with value comparison section
shorodilov Mar 12, 2023
79ed5e8
Added list operations
shorodilov Mar 12, 2023
7e4591a
Added list constructor
shorodilov Mar 12, 2023
0578406
Added tuple constructor
shorodilov Mar 12, 2023
19c3515
Added string methods placeholder
shorodilov Mar 12, 2023
e2d8239
Added brief mapping type description
shorodilov Mar 13, 2023
9894683
Removed deprecated datatypes file
shorodilov Mar 17, 2023
f856c5a
Fixed "stdtypes" footnotes
shorodilov Mar 21, 2023
f1ceb5f
DB - Aggregate functions
shorodilov Mar 23, 2023
3d47126
DB - Group by and having
shorodilov Mar 23, 2023
1fc36bf
DB - Normalization
shorodilov Mar 23, 2023
fe41592
DB - Relationships
shorodilov Mar 23, 2023
eb9213c
DB - Joins
shorodilov Mar 23, 2023
b668174
Merge branch 'gh-pages' into feature/basics
shorodilov Mar 23, 2023
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
DB - Joins
Signed-off-by: Serhii Horodilov <sgorodil@gmail.com>
  • Loading branch information
shorodilov committed Mar 23, 2023
commit eb9213c60dbfabfe51385a5e6d8464e72ca07940
234 changes: 234 additions & 0 deletions src/rdbms/relations.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,237 @@ a time.
erDiagram
employee }o--|{ employee_role : execute
role }o--|{ employee_role : assign

Joining data
============

``JOIN`` is used to *join* data fetched from multiple related tables.
To build a valid query you are to set the tables to join and parameter to use
for this operation.

Common syntax is:

::

T1 join_type T2 [ join_condition ]

There are various join types available.
Here are is some dummy data to demonstrate their purpose.

.. table:: poem

+----+------------------------+-----------+
| id | title | author_id |
+====+========================+===========+
| 1 | On the Field of Battle | 1 |
+----+------------------------+-----------+
| 2 | Moses | 2 |
+----+------------------------+-----------+
| 3 | The Forest Song | 1 |
+----+------------------------+-----------+
| 4 | In the Catacombs | null |
+----+------------------------+-----------+
| 5 | The Singing Stones | 1 |
+----+------------------------+-----------+
| 6 | Ancient Fairy Tales | null |
+----+------------------------+-----------+
| 7 | My Thoughts | 2 |
+----+------------------------+-----------+
| 8 | To Shevchenko | null |
+----+------------------------+-----------+


.. table:: author

+----+---------------+
| id | name |
+====+===============+
| 1 | Larysa Kosach |
+----+---------------+
| 2 | Ivan Franko |
+----+---------------+
| 3 | John Doe |
+----+---------------+

.. code-block:: sql

CREATE TABLE author
(
id SERIAL PRIMARY KEY,
name VARCHAR(32) NOT NULL UNIQUE
);
CREATE TABLE poem
(
id SERIAL PRIMARY KEY,
title VARCHAR(32) NOT NULL UNIQUE,
author_id INT REFERENCES author (id)
);
INSERT INTO author(name)
VALUES ('Larysa Kosach'),
('Ivan Franko'),
('John Doe');
INSERT INTO poem(title, author_id)
VALUES ('On the Field of Battle', 1),
('Moses', 2),
('The Forest Song', 1),
('In the Catacombs', null),
('The Singing Stones', 1),
('Ancient Fairy Tales', null),
('My Thoughts', 2),
('To Shevchenko', null)
;

Join types
----------

:Cross join:

.. code-block::

T1 CROSS JOIN T2

For every possible combination of rows from T1 and T2
(i.e., a Cartesian product), the joined table will contain a row consisting
of all columns in T1 followed by all columns in T2. If the tables have N
and M rows respectively, the joined table will have N * M rows.

:Qualified joins:

.. code-block::

T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON condition

The words ``INNER`` and ``OUTER`` are optional for all forms.
``INNER`` is the default; ``LEFT``, ``RIGHT`` and ``FULL`` imply ``OUTER``
join.

INNER JOIN
----------

For each row R1 of T1, the joined table has a row for each row in T2 that
satisfies the join condition with R1.

.. code-block:: sql
:caption: Inner join

SELECT p.title, a.name
FROM poem p
JOIN author a on p.author_id = a.id;

+------------------------+---------------+
| title | name |
+========================+===============+
| On the Field of Battle | Larysa Kosach |
+------------------------+---------------+
| Moses | Ivan Franko |
+------------------------+---------------+
| The Forest Song | Larysa Kosach |
+------------------------+---------------+
| The Singing Stones | Larysa Kosach |
+------------------------+---------------+
| My Thoughts | Ivan Franko |
+------------------------+---------------+

LEFT OUTER JOIN
---------------

First, an inner join is performed. Then, for each row in T1 that does not
satisfy the join condition with any row in T2, a joined row is added with null
values in columns of T2. Thus, the joined table always has at least one row for
each row in T1.

.. code-block:: sql
:caption: Left join

SELECT p.title, a.name
FROM poem p
LEFT JOIN author a on p.author_id = a.id;

+------------------------+---------------+
| title | name |
+========================+===============+
| On the Field of Battle | Larysa Kosach |
+------------------------+---------------+
| Moses | Ivan Franko |
+------------------------+---------------+
| The Forest Song | Larysa Kosach |
+------------------------+---------------+
| In the Catacombs | null |
+------------------------+---------------+
| The Singing Stones | Larysa Kosach |
+------------------------+---------------+
| Ancient Fairy Tales | null |
+------------------------+---------------+
| My Thoughts | Ivan Franko |
+------------------------+---------------+
| To Shevchenko | null |
+------------------------+---------------+

RIGHT OUTER JOIN
----------------

First, an inner join is performed. Then, for each row in T2 that does not
satisfy the join condition with any row in T1, a joined row is added with
null values in columns of T1. This is the converse of a left join: the result
table will always have a row for each row in T2.

.. code-block:: sql
:caption: Right join

SELECT p.title, a.name
FROM poem p
RIGHT JOIN author a on p.author_id = a.id;

+------------------------+---------------+
| title | name |
+========================+===============+
| On the Field of Battle | Larysa Kosach |
+------------------------+---------------+
| Moses | Ivan Franko |
+------------------------+---------------+
| The Forest Song | Larysa Kosach |
+------------------------+---------------+
| The Singing Stones | Larysa Kosach |
+------------------------+---------------+
| My Thoughts | Ivan Franko |
+------------------------+---------------+
| null | John Doe |
+------------------------+---------------+

FULL OUTER JOIN
---------------

First, an inner join is performed. Then, for each row in T1 that does not
satisfy the join condition with any row in T2, a joined row is added with
null values in columns of T2. Also, for each row of T2 that does not satisfy
the join condition with any row in T1, a joined row with null values in
the columns of T1 is added.

.. code-block:: sql
:caption: Full join

SELECT p.title, a.name
FROM poem p
FULL JOIN author a on p.author_id = a.id;

+------------------------+---------------+
| title | name |
+========================+===============+
| On the Field of Battle | Larysa Kosach |
+------------------------+---------------+
| Moses | Ivan Franko |
+------------------------+---------------+
| The Forest Song | Larysa Kosach |
+------------------------+---------------+
| In the Catacombs | null |
+------------------------+---------------+
| The Singing Stones | Larysa Kosach |
+------------------------+---------------+
| Ancient Fairy Tales | null |
+------------------------+---------------+
| My Thoughts | Ivan Franko |
+------------------------+---------------+
| To Shevchenko | null |
+------------------------+---------------+
| null | John Doe |
+------------------------+---------------+