Add lesson about set operation queries

pull/8127/head
Kamran Ahmed 1 month ago
parent 2cdeff349a
commit 03d39ad188
  1. 88
      src/data/courses/sql-mastery/chapters/multi-table-queries/lessons/set-operator-queries.md

@ -1,25 +1,25 @@
--- ---
title: Combining Query Results title: Set Operator Queries
description: Learn how to use UNION, INTERSECT, and EXCEPT to combine results from multiple queries description: Learn how to use UNION, INTERSECT, and EXCEPT to combine results from multiple queries
order: 150 order: 150
type: lesson-challenge type: lesson-challenge
setup: | setup: |
```sql ```sql
CREATE TABLE fiction_books ( CREATE TABLE fiction_book (
id INT PRIMARY KEY, id INT PRIMARY KEY,
title VARCHAR(255), title VARCHAR(255),
author VARCHAR(255), author VARCHAR(255),
price DECIMAL(10, 2) price DECIMAL(10, 2)
); );
CREATE TABLE non_fiction_books ( CREATE TABLE non_fiction_book (
id INT PRIMARY KEY, id INT PRIMARY KEY,
title VARCHAR(255), title VARCHAR(255),
author VARCHAR(255), author VARCHAR(255),
price DECIMAL(10, 2) price DECIMAL(10, 2)
); );
INSERT INTO fiction_books (id, title, author, price) INSERT INTO fiction_book (id, title, author, price)
VALUES VALUES
(1, 'The Great Gatsby', 'F. Scott Fitzgerald', 24.99), (1, 'The Great Gatsby', 'F. Scott Fitzgerald', 24.99),
(2, '1984', 'George Orwell', 19.99), (2, '1984', 'George Orwell', 19.99),
@ -27,7 +27,7 @@ setup: |
(4, 'The Hobbit', 'J.R.R. Tolkien', 29.99), (4, 'The Hobbit', 'J.R.R. Tolkien', 29.99),
(5, 'The Doors of Perception', 'Aldous Huxley', 12.99); (5, 'The Doors of Perception', 'Aldous Huxley', 12.99);
INSERT INTO non_fiction_books (id, title, author, price) INSERT INTO non_fiction_book (id, title, author, price)
VALUES VALUES
(1, 'A Brief History of Time', 'Stephen Hawking', 29.99), (1, 'A Brief History of Time', 'Stephen Hawking', 29.99),
(2, 'The Art of War', 'Sun Tzu', 19.99), (2, 'The Art of War', 'Sun Tzu', 19.99),
@ -52,11 +52,7 @@ setup: |
Sometimes you need to combine results from multiple queries into a single result set. SQL provides several set operations for this purpose: `UNION`, `UNION ALL`, `INTERSECT`, and `EXCEPT`. Sometimes you need to combine results from multiple queries into a single result set. SQL provides several set operations for this purpose: `UNION`, `UNION ALL`, `INTERSECT`, and `EXCEPT`.
## UNION and UNION ALL Let' take a look at some examples to understand how these set operations work. I have setup the following two tables `fiction_book` and `non_fiction_book` with the following data:
`UNION` combines results from two or more queries and removes duplicates. `UNION ALL` does the same but keeps duplicates.
I have setup the following two tables `fiction_books` and `non_fiction_books` with the following data:
| id | title | author | price | | id | title | author | price |
| --- | ----------------------- | ------------------- | ----- | | --- | ----------------------- | ------------------- | ----- |
@ -74,16 +70,20 @@ I have setup the following two tables `fiction_books` and `non_fiction_books` wi
| 4 | Pride and Prejudice: A Study Guide | John Smith | 12.99 | | 4 | Pride and Prejudice: A Study Guide | John Smith | 12.99 |
| 5 | The Doors of Perception | Aldous Huxley | 12.99 | | 5 | The Doors of Perception | Aldous Huxley | 12.99 |
Let's start with the `UNION` operations.
`UNION` combines results from two or more queries and removes duplicates. `UNION ALL` does the same but keeps duplicates.
### UNION Example ### UNION Example
Let's find all books across fiction and non-fiction categories: Let's find all books across `fiction_book` and `non_fiction_book` tables using a `UNION` operation:
```sql ```sql
SELECT title, author, price SELECT title, author, price
FROM fiction_books FROM fiction_book
UNION UNION
SELECT title, author, price SELECT title, author, price
FROM non_fiction_books FROM non_fiction_book
ORDER BY title; ORDER BY title;
``` ```
@ -101,16 +101,16 @@ The query above will combine the results from both the queries and remove any du
| The Great Gatsby | F. Scott Fitzgerald | 24.99 | | The Great Gatsby | F. Scott Fitzgerald | 24.99 |
| The Hobbit | J.R.R. Tolkien | 29.99 | | The Hobbit | J.R.R. Tolkien | 29.99 |
Notice how the `The Doors of Perception` book is only listed once even though it appears in both the `fiction_books` and `non_fiction_books` tables. Notice how the `The Doors of Perception` book is only listed once even though it appears in both the `fiction_book` and `non_fiction_book` tables.
### UNION ALL Example ### UNION ALL Example
If you want to keep duplicates, use UNION ALL: If you want to keep duplicates, use UNION ALL:
```sql ```sql
SELECT title, author, price FROM fiction_books SELECT title, author, price FROM fiction_book
UNION ALL UNION ALL
SELECT title, author, price FROM non_fiction_books SELECT title, author, price FROM non_fiction_book
ORDER BY title; ORDER BY title;
``` ```
@ -133,12 +133,12 @@ Notice how the `The Doors of Perception` book is listed twice.
## INTERSECT ## INTERSECT
`INTERSECT` returns only the rows that appear in both result sets. Let's find books that are in both the `fiction_books` and `non_fiction_books` tables: `INTERSECT` returns only the rows that appear in both result sets. Let's find books that are in both the `fiction_book` and `non_fiction_book` tables:
```sql ```sql
SELECT title, author FROM fiction_books SELECT title, author FROM fiction_book
INTERSECT INTERSECT
SELECT title, author FROM non_fiction_books; SELECT title, author FROM non_fiction_book;
``` ```
This will return: This will return:
@ -149,12 +149,12 @@ This will return:
## EXCEPT ## EXCEPT
`EXCEPT` returns rows from the first query that don't appear in the second query. Let's find the books in the `fiction_books` table that aren't in the `non_fiction_books` table: `EXCEPT` returns rows from the first query that don't appear in the second query. Let's find the books in the `fiction_book` table that aren't in the `non_fiction_book` table:
```sql ```sql
SELECT title, author FROM fiction_books SELECT title, author FROM fiction_book
EXCEPT EXCEPT
SELECT title, author FROM non_fiction_books SELECT title, author FROM non_fiction_book
ORDER BY title; ORDER BY title;
``` ```
@ -177,24 +177,48 @@ For example, below is an invalid query:
```sql ```sql
-- ERROR: each UNION query must have the same number of columns -- ERROR: each UNION query must have the same number of columns
SELECT title, author FROM fiction_books SELECT title, author FROM fiction_book
UNION UNION
SELECT title, author, price FROM non_fiction_books; SELECT title, author, price FROM non_fiction_book;
``` ```
Because the `fiction_books` table has 2 columns and the `non_fiction_books` table has 3 columns, the query will return an error. The above query will return an error because the `fiction_book` table has 2 columns and the `non_fiction_book` table has 3 columns.
Similary if we try to combine the following two queries: Similary if we try to combine the following two queries:
```sql ```sql
-- ERROR: UNION types numeric and character varying cannot be matched -- ERROR: UNION types numeric and character varying cannot be matched
SELECT title, price FROM fiction_books SELECT title, price FROM fiction_book
UNION UNION
SELECT title, author FROM non_fiction_books; SELECT title, author FROM non_fiction_book;
``` ```
This will also return an error because the `price` column from the first query doesn't have the same data type as the `author` column from the second query. This will also return an error because the `price` column from the first query doesn't have the same data type as the `author` column from the second query.
Also, another important thing to note for the set operations is that the column names in the result set will be the column names from the first query. For example, if we run the following query:
```sql
SELECT title, author as 'writer_name' FROM fiction_book
UNION
SELECT title, author FROM non_fiction_book;
```
The output will be:
| title | writer_name |
| ---------------------------------- | ------------------- |
| A Brief History of Time | Stephen Hawking |
| The Hobbit | J.R.R. Tolkien |
| The Great Gatsby | F. Scott Fitzgerald |
| Sapiens | Yuval Noah Harari |
| The Art of War | Sun Tzu |
| Pride and Prejudice: A Study Guide | John Smith |
| 1984 | George Orwell |
| The Doors of Perception | Aldous Huxley |
| Pride and Prejudice | Jane Austen |
Notice how it took the `writer_name` column alias from the first query for the name of the column in the result set.
## Challenge Time! 🎯 ## Challenge Time! 🎯
Using the provided tables, write queries to: Using the provided tables, write queries to:
@ -209,22 +233,22 @@ Using the provided tables, write queries to:
```sql ```sql
-- 1. Books that cost $19.99 -- 1. Books that cost $19.99
SELECT title, author, 'Fiction' as category SELECT title, author, 'Fiction' as category
FROM fiction_books FROM fiction_book
WHERE price = 19.99 WHERE price = 19.99
UNION UNION
SELECT title, author, 'Non-Fiction' as category SELECT title, author, 'Non-Fiction' as category
FROM non_fiction_books FROM non_fiction_book
WHERE price = 19.99; WHERE price = 19.99;
-- 2. Authors in both categories -- 2. Authors in both categories
SELECT author FROM fiction_books SELECT author FROM fiction_book
INTERSECT INTERSECT
SELECT author FROM non_fiction_books; SELECT author FROM non_fiction_book;
-- 3. Summer reads not in fiction -- 3. Summer reads not in fiction
SELECT title, author FROM summer_reads SELECT title, author FROM summer_reads
EXCEPT EXCEPT
SELECT title, author FROM fiction_books; SELECT title, author FROM fiction_book;
``` ```
</details> </details>
Loading…
Cancel
Save