经典sql题(九)SQL 查询详细指南总结二
示例
综合上一章内容,编写一个示例 SQL 查询:
SELECT DISTINCT a.user_id, COALESCE(b.amount, 0) AS amount
FROM users a
LEFT JOIN transactions b ON a.user_id = b.user_id
WHERE a.status = 'active'
GROUP BY a.user_id
HAVING COUNT(b.transaction_id) > 0
ORDER BY amount DESC
LIMIT 10;
SQL 查询的执行步骤图表说明:
-
FROM 和 JOIN:
- 连接
users
表和transactions
表。 - 使用
LEFT JOIN
确保users
表中的所有行都被保留,即使在transactions
中没有匹配。
- 连接
-
WHERE:
- 过滤
users
表中status
为'active'
的行。
- 过滤
-
GROUP BY:
- 将结果按照
user_id
分组。
- 将结果按照
-
HAVING:
- 过滤之前分组的结果,保留
transactions
表中transaction_id
计数大于 0 的组。
- 过滤之前分组的结果,保留
-
SELECT:
- 提取每个分组的
user_id
和amount
(使用COALESCE
将NULL
值替换为 0)。
- 提取每个分组的
-
ORDER BY:
- 按
amount
降序排列结果。
- 按
-
DISTINCT:
- 确保结果中
user_id
是唯一的。
- 确保结果中
-
LIMIT:
- 仅返回前 10 行结果。
步骤图表
┌───────────────────────────────────────────┐
│ FROM & JOIN │
│ users a LEFT JOIN transactions b │
└───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ WHERE │
│ a.status = 'active' │
└───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ GROUP BY │
│ a.user_id │
└───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ HAVING │
│ COUNT(b.transaction_id) > 0 │
└───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ SELECT │
│ DISTINCT a.user_id, COALESCE(b.amount, 0) │
└───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ ORDER BY │
│ amount DESC │
└───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ LIMIT │
│ 10 │
└───────────────────────────────────────────┘
为了演示这条 SQL 查询的执行,可以先定义数据库表架构并插入一些示例数据。
数据库表架构
表 1:users
user_id | name | status |
---|---|---|
1 | Alice | active |
2 | Bob | inactive |
3 | Charlie | active |
4 | David | active |
表 2:transactions
transaction_id | user_id | amount |
---|---|---|
1 | 1 | 100 |
2 | 1 | 200 |
3 | 3 | 150 |
4 | 4 | NULL |
执行步骤及结果
1. FROM 和 JOIN
SELECT a.user_id, b.amount
FROM users a
LEFT JOIN transactions b ON a.user_id = b.user_id;
user_id | amount |
---|---|
1 | 100 |
1 | 200 |
2 | NULL |
3 | 150 |
4 | NULL |
2. WHERE
WHERE a.status = 'active'
user_id | amount |
---|---|
1 | 100 |
1 | 200 |
3 | 150 |
4 | NULL |
3. GROUP BY
GROUP BY a.user_id
user_id | amount (example aggregation) |
---|---|
1 | 100, 200 |
3 | 150 |
4 | NULL |
4. HAVING
HAVING COUNT(b.transaction_id) > 0
user_id | amount (example aggregation) |
---|---|
1 | 100, 200 |
3 | 150 |
5. SELECT & COALESCE
SELECT DISTINCT a.user_id, COALESCE(b.amount, 0) AS amount
user_id | amount |
---|---|
1 | 100 |
1 | 200 |
3 | 150 |
6. ORDER BY
ORDER BY amount DESC
user_id | amount |
---|---|
1 | 200 |
3 | 150 |
1 | 100 |
7. DISTINCT
在这个例子中已经处理。
8. LIMIT
LIMIT 10
结果与 ORDER BY 相同,因为只有 3 行。
最终结果
user_id | amount |
---|---|
1 | 200 |
3 | 150 |
1 | 100 |
这些步骤展示了 SQL 查询如何逐步处理数据,应用过滤、分组、排序和限制操作,最后返回所需结果。