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.
|