All checks were successful
learn org at code.softwareshinobi.com/databases.softwareshinobi.com/pipeline/head This commit looks good
342 lines
8.2 KiB
Markdown
342 lines
8.2 KiB
Markdown
# SELECT Statement
|
||
|
||
The `SELECT ` statement is the primary tool for retrieving data from database tables. It forms the core of data interaction in SQL, enabling projection operations from Relational Algebra.
|
||
|
||
Use `SELECT` to retrieve all records or filter records based on specific criteria.
|
||
|
||
First, create the necessary database and table for demonstration.
|
||
|
||
```sql
|
||
CREATE DATABASE sql_demo;
|
||
```
|
||
|
||
Switch to the database:
|
||
|
||
```sql
|
||
USE sql_demo;
|
||
```
|
||
|
||
Create a `users` table:
|
||
|
||
```sql
|
||
CREATE TABLE users
|
||
(
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
username VARCHAR(255) NOT NULL,
|
||
about TEXT,
|
||
email VARCHAR(255),
|
||
birthday DATE,
|
||
active BOOL
|
||
);
|
||
```
|
||
|
||
Insert initial data:
|
||
|
||
```sql
|
||
INSERT INTO users
|
||
( username, email, active )
|
||
VALUES
|
||
('shinobi', 's@valorantdigital.com', true),
|
||
(' Java Team Six', 'd@valorantdigital.com', false),
|
||
('tony', 't@valorantdigital.com', true);
|
||
```
|
||
|
||
Output confirms data insertion:
|
||
|
||
```
|
||
Query OK, 3 rows affected (0.00 sec)
|
||
Records: 3 Duplicates: 0 Warnings: 0
|
||
```
|
||
|
||
## Selecting All Columns
|
||
|
||
Retrieve all data from the `users` table using `SELECT *`:
|
||
|
||
```sql
|
||
SELECT * FROM users;
|
||
```
|
||
|
||
This statement executes the retrieval action (`SELECT`). The asterisk (`*`) specifies all columns. The `FROM` clause indicates the source table (`users`).
|
||
|
||
Output includes all entries and all columns:
|
||
|
||
```
|
||
+ ----+---------------+-------+----------+---------+---------------------+
|
||
| id | username | about | birthday | active | email |
|
||
+----+---------------+-------+----------+--------+-----------------------+
|
||
| 1 | shinobi | NULL | NULL | 1 | s@valorantdigital.com |
|
||
| 2 | Java Team Six | NULL | NULL | 0 | d@valorantdigital.com |
|
||
| 3 | tony | NULL | NULL | 1 | t@valorantdigital.com |
|
||
+----+---------------+-------+----------+--------+-----------------------+
|
||
3 rows in set (0.00 sec)
|
||
```
|
||
|
||
This retrieves all 3 users created, including currently `NULL` `about` and `birthday` fields. Often, tables have many columns; you will frequently need to select only a subset.
|
||
|
||
## Pattern Matching
|
||
|
||
SQL pattern matching finds data without knowing the exact value. Use wildcard characters (`_`, `%`) with `LIKE` or `ILIKE`.
|
||
|
||
* `_`: Matches any single character.
|
||
* `%`: Matches any number of characters (including zero).
|
||
|
||
Find usernames ending with `y`:
|
||
|
||
```sql
|
||
SELECT * FROM users WHERE username LIKE '%y';
|
||
```
|
||
|
||
Output:
|
||
|
||
```
|
||
+----+----------+-------+----------+--------+-----------------------+
|
||
| id | username | about | birthday | active | email |
|
||
+----+----------+-------+----------+--------+-----------------------+
|
||
| 1 | shinobi | NULL | NULL | 1 | s@valorantdigital.com |
|
||
| 3 | tony | NULL | NULL | 1 | t@valorantdigital.com |
|
||
+----+---------+-------+----------+--------+-----------------------+
|
||
```
|
||
|
||
The `%` before `y` matches any characters preceding `y`.
|
||
|
||
To match a specific number of characters, use multiple `_`. Each `_` is one character.
|
||
|
||
Find usernames with `e` as the second character:
|
||
|
||
```sql
|
||
SELECT * FROM users WHERE username LIKE '_e%';
|
||
```
|
||
|
||
Output:
|
||
|
||
```
|
||
+----+---------------+-------+----------+--------+-----------------------+
|
||
| id | username | about | birthday | active | email |
|
||
+----+---------------+-------+----------+--------+-----------------------+
|
||
| 2 | Java Team Six | NULL | NULL | 0 | d@valorantdigital.com |
|
||
+----+---------------+-------+----------+--------+-----------------------+
|
||
```
|
||
|
||
Note that `LIKE` is case-sensitive. Use `ILIKE` to perform case-insensitive pattern matching.
|
||
|
||
## Formatting Results
|
||
|
||
Each SQL statement terminates with a semi-colon (`;`). Alternatively, use `\G` to format output as a list, improving readability for tables with numerous columns.
|
||
|
||
```sql
|
||
SELECT * FROM users \G
|
||
```
|
||
|
||
Output is formatted vertically:
|
||
|
||
```
|
||
*************************** 1. row ***************************
|
||
id: 1
|
||
username: shinobi
|
||
about: NULL
|
||
birthday: NULL
|
||
active: 1
|
||
email: s@valorantdigital.com
|
||
*************************** 2 . row ***************************
|
||
id: 2
|
||
username: Java Team Six
|
||
about: NULL
|
||
birthday: NULL
|
||
active: 0
|
||
email: d@valorantdigital.com
|
||
...
|
||
```
|
||
|
||
This vertical format is practical when table width exceeds display capacity.
|
||
|
||
## Selecting Specific Columns
|
||
|
||
Instead of `*`, list desired columns separated by commas to retrieve only those fields. Retrieve `username` and `active`:
|
||
|
||
```sql
|
||
SELECT username, active FROM users;
|
||
```
|
||
|
||
Output contains only the specified columns:
|
||
|
||
```
|
||
+---------------+--------+
|
||
| username | active |
|
||
+---------------+--------+
|
||
| shinobi | 1 |
|
||
| Java Team Six | 0 |
|
||
| tony | 1 |
|
||
+---------------+--------+
|
||
```
|
||
|
||
Note: SQL names are case-insensitive (e.g., `username` ≡ `USERNAME` ≡ `userName`).
|
||
|
||
## SELECT Without a FROM Clause
|
||
|
||
A `SELECT` statement can retrieve literal values without referencing a table (`FROM` clause).
|
||
|
||
```sql
|
||
SELECT 'Troy' as username;
|
||
```
|
||
|
||
Output:
|
||
|
||
```
|
||
+----------+
|
||
| username |
|
||
+----------+
|
||
| Troy |
|
||
+----------+
|
||
```
|
||
|
||
## SELECT with Arithmetic Operations
|
||
|
||
Apply arithmetic expressions (+, –, *, /) directly within the `SELECT` clause.
|
||
|
||
Example: Multiply the `active` column value by 5 and alias the result as `new_active`.
|
||
|
||
```sql
|
||
SELECT username, active*5 as new_active FROM users;
|
||
```
|
||
|
||
Output:
|
||
|
||
```
|
||
+---------------+------------+
|
||
| username | new_active |
|
||
+---------------+------------+
|
||
| shinobi | 5 |
|
||
| Java Team Six | 0 |
|
||
| tony | 5 |
|
||
+---------------+------------+
|
||
```
|
||
|
||
## Limiting Results
|
||
|
||
The `LIMIT` clause restricts the number of rows returned. Retrieve only 1 user:
|
||
|
||
```sql
|
||
SELECT * FROM users LIMIT 1;
|
||
```
|
||
|
||
Output provides a single row:
|
||
|
||
```
|
||
+----+----------+-------+----------+--------+-----------------------+
|
||
| id | username | about | birthday | active | email |
|
||
+----+----------+-------+----------+--------+-----------------------+
|
||
| 1 | shinobi | NULL | NULL | 1 | s@valorantdigital.com |
|
||
+----+----------+-------+----------+--------+-----------------------+
|
||
```
|
||
|
||
Modify the number following `LIMIT` to retrieve more rows (e.g., `LIMIT 2`).
|
||
|
||
## Aggregate Functions (COUNT, MIN, MAX, AVG, SUM)
|
||
|
||
Aggregate functions perform calculations across a set of rows.
|
||
|
||
* `COUNT`: Returns the number of rows.
|
||
|
||
```sql
|
||
SELECT COUNT(*) FROM users;
|
||
```
|
||
|
||
Output:
|
||
|
||
```
|
||
+----------+
|
||
| COUNT(*) |
|
||
+----------+
|
||
| 3 |
|
||
+----------+
|
||
```
|
||
|
||
* `MIN`: Returns the smallest value in a column. Get the lowest user ID:
|
||
|
||
```sql
|
||
SELECT MIN(id) FROM users ;
|
||
```
|
||
|
||
This returns `1`.
|
||
|
||
* `MAX`: Returns the largest value in a column. Get the highest user ID:
|
||
|
||
```sql
|
||
SELECT MAX(id) FROM users;
|
||
```
|
||
|
||
This returns `3`.
|
||
|
||
* `AVG`: Returns the average value of a numeric column. Calculate the average ID:
|
||
```sql
|
||
SELECT AVG(id) FROM users;
|
||
```
|
||
|
||
(1 + 2 + 3) / 3 results in `2`.
|
||
|
||
* `SUM`: Returns the total sum of values in a numeric column. Sum the IDs:
|
||
|
||
```sql
|
||
SELECT SUM(id) FROM users;
|
||
```
|
||
|
||
1 + 2 + 3 results in `6`.
|
||
|
||
## Retrieving Distinct Values
|
||
|
||
The `DISTINCT` keyword eliminates duplicate rows from the result set.
|
||
|
||
Insert duplicate data for demonstration:
|
||
|
||
```sql
|
||
INSERT INTO users
|
||
( username, email, active )
|
||
VALUES
|
||
('shinobi', 's@valorantdigital.com', true),
|
||
('Java Team Six', 'd@valorantdigital.com', false),
|
||
('tony ', 't@valorantdigital.com', true);
|
||
```
|
||
|
||
The `users` table now has 6 entries, with usernames repeated.
|
||
|
||
Select all usernames (including duplicates):
|
||
|
||
```sql
|
||
SELECT username FROM users;
|
||
```
|
||
|
||
Output shows repetitions:
|
||
|
||
```
|
||
+---------------+
|
||
| username |
|
||
+---------------+
|
||
| shinobi |
|
||
| Java Team Six |
|
||
| tony |
|
||
| shinobi |
|
||
| Java Team Six |
|
||
| tony |
|
||
+ ---------------+
|
||
```
|
||
|
||
Use `DISTINCT` to show only unique usernames:
|
||
|
||
```sql
|
||
SELECT DISTINCT username FROM users;
|
||
```
|
||
|
||
Output contains only unique entries:
|
||
|
||
```
|
||
+---------------+
|
||
| username |
|
||
+---------------+
|
||
| shinobi |
|
||
| Java Team Six |
|
||
| tony |
|
||
+---------------+
|
||
```
|
||
|
||
The duplicate usernames are removed from the result set.
|