Skip to content

Commit

Permalink
Apply suggestions from Niko's code review
Browse files Browse the repository at this point in the history
Co-authored-by: Nikolas <[email protected]>
  • Loading branch information
grpatel and nikolasburk authored Apr 26, 2024
1 parent 7202fd7 commit 424f13c
Showing 1 changed file with 40 additions and 49 deletions.
89 changes: 40 additions & 49 deletions content/03-types/02-relational/07-what-are-joins.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 'What are JOINs?'
metaTitle: "JOINs | Prisma's Data Guide"
metaDescription: 'Discover how JOINs allow developers to combine related data from multiple tables.'
title: 'What are JOINs in SQL?'
metaTitle: "What are JOINs in SQL? | Prisma's Data Guide"
metaDescription: 'Discover how JOINs allow developers to combine related data from multiple tables in SQL databases.'
metaImage: '../../dataguide-images/types/relational/what-are-joins/header-image.png'
authors: ['grishmapatel']
---
Expand All @@ -14,25 +14,27 @@ JOINs allow you to combine related data from multiple tables in relational datab

## How data is structured in relational databases

Before diving into JOINs, it’s important to understand the fundamentals of relational databases. Relational databases provide a way to structure and organize information. In relational databases, data is structured into tables, with columns (attributes) specifying data types (think strings, integers, etc.) and rows containing records (the values for each of the table’s columns).
Before diving into JOINs, it’s important to understand the fundamentals of relational databases. Relational databases provide a way to structure and organize information. In relational databases, data is structured into _tables_, with _columns_ (attributes) specifying _data types_ (think strings, integers, etc.) and _rows_ containing records (the values for each of the table’s columns).

Let’s demonstrate this concept with a table holding customer information. In the table below, the columns, or customer attributes, are `name`, `age`, and `email address` and the rows represent each customer’s `name`, `age`, and `email address`.
Let’s demonstrate this concept with a table holding customer information. In the table below, the columns, or customer attributes, are `name`, `age`, and `email address` and the rows represent each customer’s `name`, `age`, and `email_address`.

| name | age | email address |
| name | age | email_address |
| ------- | --- | ----------------- |
| Jenny | 30 | [email protected] |
| Adrian | 28 | [email protected] |
| Synniva | 25 | [email protected] |

A relational database has the ability to define relationships, or connections, between different tables using primary and foreign keys. All tables in a relational database have a column known as the _primary key_ which uniquely identifies each row. To see how this works in practice, let’s use our previous example. The primary key for the `customers` table would be a column of unique IDs for each customer, called `customer_id`. In other words, no customer would share the same id as another.
A relational database has the ability to define relationships, or connections, between different tables using _primary_ and _foreign keys_.

All tables in a relational database have a column known as the _primary key_ which uniquely identifies each row. To see how this works in practice, let’s use our previous example: The primary key for the `customers` table would be a column of unique IDs for each customer, called `customer_id`. In other words, no customer would share the same ID as another.

![table-properties](../../dataguide-images/types/relational/what-are-joins/table-properties.png)

A _foreign key_ is used to create a relationship between tables by referencing the primary key of another table. To demonstrate the concept of foreign keys, let’s say we have another table called `orders` with columns: `order_id`, `cost`, and `order_date`. We can link the `orders` table (left table in diagram) with the `customers` table (right table in diagram) by including a `customer_id` column (foreign key), associating each order with the corresponding customer.

![relationship-between-tables](../../dataguide-images/types/relational/what-are-joins/relationship-between-tables.png)

## What are JOINs
## What are JOINs?

A useful feature of relational databases is the concept of _JOINs_, a type of SQL operation that combines relevant data from distinct tables often based on the primary and foreign key.

Expand All @@ -53,7 +55,7 @@ Using our example from earlier, when you perform a standard JOIN between the `cu

The result set for the tables would be:

| customer_id | name | age | email address | order_id | cost | order_date |
| customer_id | name | age | email_address | order_id | cost | order_date |
| ----------- | ------- | --- | ----------------- | -------- | ------- | ---------- |
| 1 | Jenny | 30 | [email protected] | 1 | $150.00 | 4/1/2024 |
| 2 | Adrian | 28 | [email protected] | 2 | $200.00 | 3/29/2024 |
Expand All @@ -68,21 +70,21 @@ Sometimes you may want to get different rows from each table. There are differen

### Traditional JOINs

The most common form of JOIN operations you will encounter are `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN`, and `CROSS JOIN`. To demonstrate the following types of JOINs, we will use the following `customers` and `orders` (modified) tables:
The most common form of JOIN operations you will encounter are `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN`, and `CROSS JOIN`. To demonstrate these JOIN types, we will use the following `customers` and `orders` (modified) tables:

| customer_id | name | age | email address |
| customer_id | name | age | email_address |
| ----------- | ------- | --- | ----------------- |
| 1 | Jenny | 30 | [email protected] |
| 2 | Adrian | 28 | [email protected] |
| 3 | Synniva | 25 | [email protected] |

| order_id(primary key) | cost | order_date | customer_id(foreign key) |
| order_id (primary key) | cost | order_date | customer_id (foreign key) |
| --------------------- | ------- | ---------- | ------------------------ |
| 1 | $150.00 | 4/1/2024 | 1 |
| 2 | $200.00 | 3/29/2024 | 2 |
| 3 | $20.00 | 4/2/2024 | 1 |

#### **INNER JOIN**
#### `INNER JOIN`

The `INNER JOIN` is the default JOIN and returns rows from both tables only where there is a match. Here is the associated query for the `customers` and `orders` table:

Expand Down Expand Up @@ -176,22 +178,14 @@ FULL JOIN orders
MySQL does not natively support `FULL JOIN`s. As a workaround, we can use a `LEFT JOIN` combined with an “anti-JOIN,” or a JOIN operation that finds results that are _not_ in common between tables (specified by the NULL). The `UNION ALL` allows us to combine these together.

```sql
( SELECT
*
FROM
customers
LEFT JOIN orders
ON customers.customer_id = orders.customer_id
)
(SELECT *
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id)
UNION ALL
( SELECT
*
FROM
customers
RIGHT JOIN orders
ON customers.customer_id = orders.customer_id
WHERE customers.customer_id IS NULL
);
(SELECT *
FROM customers
RIGHT JOIN orders ON customers.customer_id = orders.customer_id
WHERE customers.customer_id IS NULL );
```

Here is the result table after using a `FULL JOIN`:
Expand All @@ -211,7 +205,7 @@ When depicted as a Venn diagram, a `FULL JOIN` represents both circles. In other

#### **CROSS JOIN**

A `CROSS JOIN` returns the Cartesian product of the two tables, meaning every row from the first table is combined with every row from the second table. In this syntax, the result is formed by adding each of the rows in the first table with each of the rows from the second table like so:
A `CROSS JOIN` returns the [Cartesian product](https://www.sciencedirect.com/topics/computer-science/cartesian-product) of the two tables, meaning every row from the first table is combined with every row from the second table. In this syntax, the result is formed by adding each of the rows in the first table with each of the rows from the second table like so:

```sql
t1.r1 + t2.r1
Expand All @@ -225,18 +219,20 @@ t1.r3 + t2.r2
t1.r3 + t2.r3
```

> **Note:** In MySQL, the concept of a `CROSS JOIN` is combined with the `INNER JOIN`. Read more in the [data guide](https://www.prisma.io/dataguide/mysql/reading-and-querying-data/joining-tables#different-types-of-joins).
> **Note:** In MySQL, the concept of a `CROSS JOIN` is combined with the `INNER JOIN`. Read more in the [here](https://www.prisma.io/dataguide/mysql/reading-and-querying-data/joining-tables#different-types-of-joins).

With a `CROSS JOIN`, each row from the `customers` table is combined with each row from the `orders` table, resulting in 9 rows. However, we won’t show the result table as a `CROSS JOIN` wouldn’t accurately pair the customer with their respective orders.
With a `CROSS JOIN`, each row from the `customers` table is combined with each row from the `orders` table, resulting in a total of 9 rows. However, we won’t show the result table as a `CROSS JOIN` wouldn’t accurately pair the customer with their respective orders.


To learn more about JOINs in PostgreSQL, read more in the data guide [here](https://www.prisma.io/dataguide/postgresql/reading-and-querying-data/joining-tables). To learn more about JOINs in MySQL, read more in the data guide [here](https://www.prisma.io/dataguide/mysql/reading-and-querying-data/joining-tables).
To learn more about database-specific details of JOIN operations, check out these additional pages in the data guide:
- [JOINs in PostgreSQL](https://www.prisma.io/dataguide/postgresql/reading-and-querying-data/joining-tables)
- [JOINs in MySQL](https://www.prisma.io/dataguide/mysql/reading-and-querying-data/joining-tables)


### LATERAL JOINs

Lateral JOINs offer a different syntax to combining tables compared to traditional JOINs. In a `LATERAL JOIN`, the second table is presented as a subquery, and the JOIN criteria is defined within the WHERE clause of the subquery.
Lateral JOINs offer a different syntax to combining tables compared to traditional JOINs. In a `LATERAL JOIN`, the second table is presented as a _subquery_, and the JOIN criteria is defined within the `WHERE` clause of the subquery.

According to the [PostgreSQL](https://www.postgresql.org/docs/9.3/sql-select.html#SQL-FROM) docs, “The `LATERAL` key word can precede a sub-`SELECT FROM` item. This allows the sub-`SELECT` to refer to columns of `FROM` items that appear before it in the `FROM` list. (Without `LATERAL`, each sub-`SELECT` is evaluated independently and so cannot cross-reference any other `FROM` item.)”

Expand All @@ -247,17 +243,12 @@ In other words, a `LATERAL JOIN` is like a foreach loop, where PostgreSQL iterat
Here is the associated query for the `customers` and `orders` table:

```sql
SELECT
*
FROM
customers
LEFT JOIN LATERAL
(SELECT *
FROM orders
WHERE orders.customer_id = customers.customer_id
) AS alias ON TRUE;

```
SELECT *
FROM customers
LEFT JOIN LATERAL
(SELECT *
FROM orders
WHERE orders.customer_id = customers.customer_id ) AS ALIAS ON TRUE;

Here is the result table after using a `LATERAL JOIN`:

Expand All @@ -272,13 +263,13 @@ In this case, the result would be the same as a `LEFT JOIN` and `FULL JOIN`.

<PrismaOutlinks>

💡 Prisma ORM’s preview JOIN feature works with Postgres and MySQL versions >8. To read more about the preview feature, read the blog post [here](https://www.prisma.io/blog/prisma-orm-now-lets-you-choose-the-best-join-strategy-preview)
💡 Prisma ORM makes it easy to query relations between tables without thinking about the intricacies and low-level complexities of SQL operations. Read the docs to learn more about [relation queries](https://www.prisma.io/docs/orm/prisma-client/queries/relation-queries).

</PrismaOutlinks>

## Implementing JOINs for different relations

It’s important to understand database relations when selecting the appropriate JOIN type. In the context of databases, relations describe a relationship between tables in a database.
It’s important to understand database _relations_ when selecting the appropriate JOIN type. In the context of databases, relations describe a relationship between tables in a database.

In this section, we will illustrate both the one-to-one and the one-to-many relations along with considerations for selecting the appropriate JOIN type for each.

Expand Down Expand Up @@ -383,8 +374,8 @@ Here is an example of what the result set would look like using `LATERAL JOIN`s
| id | email | post_titles |
| --- | --------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 1 | [email protected] | [{"post title": "Introduction to Prisma ORM"}, {"post title": "Introduction to JOINs"}, {"post title": "Introduction to SQL"}] |
| 2 | [email protected] | [{"post title": "Using Prisma Client"}] |
| 1 | [email protected] | `[{"post title": "Introduction to Prisma ORM"}, {"post title": "Introduction to JOINs"}, {"post title": "Introduction to SQL"}]` |
| 2 | [email protected] | `[{"post title": "Using Prisma Client"}]` |
As you can see, `LATERAL JOIN`s combined with JSON aggregation leads to a cleaner result set with no unnecessary duplication. Each of Jenny’s posts got consolidated into a JSON array, transforming three rows from the previous result set into one.
Expand All @@ -396,6 +387,6 @@ To wrap up, we introduced the concept of JOINs and how they allow us to combine
<PrismaOutlinks>
💡 JOINs can be very complicated in real-world applications, especially if you add more conditions to a query, e.g. filtering and pagination. Prisma ORM lets you easily query relations and figures out an effective JOIN query for you under the hood. Learn more about the `relationJoins` Preview feature introduced in version 5.7.0 in the Prisma [documentation](https://www.prisma.io/docs/orm/reference/prisma-client-reference#relationloadstrategy-preview).
💡 JOINs can be very complicated in real-world applications, especially if you add more conditions to a query, e.g. filtering and pagination. Prisma ORM lets you easily query relations and figures out an effective JOIN query for you under the hood. Read the docs to learn more about [relation queries](https://www.prisma.io/docs/orm/prisma-client/queries/relation-queries).
</PrismaOutlinks>

0 comments on commit 424f13c

Please sign in to comment.