本文目录导读:

编写数据库查询脚本是数据管理和分析的核心技能,为了给你最实用、专业的指导,我将从基础语法、不同数据库的差异以及最佳实践三个层面来讲解。
第一部分:核心基础(SQL 标准语法)
无论你使用 MySQL、PostgreSQL、SQL Server 还是 Oracle,以下语法是通用的。
基本查询结构
-- 注释:单行注释用两个短横线,多行用 /* */ SELECT 列名1, 列名2, ... -- 指定你要查询哪些列 FROM 表名 -- 指定从哪个表查 WHERE 条件 -- 筛选行(可选) GROUP BY 列名 -- 分组聚合(可选) HAVING 聚合条件 -- 对分组结果筛选(可选) ORDER BY 列名 [ASC|DESC]; -- 排序(可选)
常用子句详解
-
SELECT:你可以用 选择所有列,但生产环境中强烈建议显式列出列名,以提高性能。-- 不推荐 SELECT * FROM users; -- 推荐 SELECT id, username, email, signup_date FROM users;
-
WHERE:用于过滤记录。-- 精确匹配 SELECT * FROM orders WHERE status = 'paid'; -- 范围查询 SELECT * FROM products WHERE price BETWEEN 10 AND 100; -- 模糊匹配 SELECT * FROM customers WHERE name LIKE '%张%'; -- % 表示任意字符 -- 多条件 SELECT * FROM employees WHERE department = 'IT' AND salary > 5000; SELECT * FROM products WHERE category = 'A' OR category = 'B';
-
JOIN:连接多张表(这是查询最强大的功能之一)。-- 内连接:返回两张表中匹配的记录 SELECT u.username, o.order_amount FROM users u INNER JOIN orders o ON u.id = o.user_id; -- 左外连接:返回左表所有记录,右表无匹配则显示 NULL SELECT u.username, o.order_amount FROM users u LEFT JOIN orders o ON u.id = o.user_id; -- 右外连接:与 LEFT JOIN 相反 -- 全外连接:MySQL 不支持但其他支持,表示并集
-
GROUP BY与聚合函数-- 常用聚合函数: COUNT, SUM, AVG, MAX, MIN SELECT department, AVG(salary) as avg_salary, COUNT(*) as emp_count FROM employees GROUP BY department HAVING avg_salary > 6000; -- HAVING 是对分组后的结果过滤,WHERE 是对分组前过滤
-
ORDER BY与分页-- 排序 SELECT * FROM products ORDER BY price DESC, name ASC; -- 分页 (不同数据库语法不同) -- MySQL / PostgreSQL SELECT * FROM products LIMIT 10 OFFSET 20; -- 第3页,每页10条 -- SQL Server SELECT * FROM products ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
第二部分:不同数据库的特定语法差异
写脚本时注意这些差异可以避免报错。
| 特性 | MySQL | PostgreSQL | SQL Server | Oracle |
|---|---|---|---|---|
| 字符串连接 | CONCAT(a, b) 或 a \|\| b |
a \|\| b 或 CONCAT() |
a + b (注意类型) |
a \|\| b |
| 当前日期 | CURDATE(), NOW() |
CURRENT_DATE, NOW() |
GETDATE() |
SYSDATE |
| 文本长度 | LENGTH() |
LENGTH() 或 CHAR_LENGTH() |
LEN() |
LENGTH() |
| 系统表/视图 | information_schema |
pg_catalog 或 information_schema |
sys.tables, INFORMATION_SCHEMA |
ALL_TABLES |
| 分页语法 | LIMIT x OFFSET y |
LIMIT x OFFSET y |
OFFSET...FETCH |
ROWNUM 或 FETCH (12c+) |
| 查询前N条 | LIMIT 10 |
LIMIT 10 |
SELECT TOP 10 ... |
FETCH FIRST 10 ROWS ONLY |
第三部分:真实场景脚本示例
假设我们有一个电商数据库。
场景 1:查询“最近30天活跃用户及其订单总额”
-- 目标:找出活跃用户及其消费能力
SELECT
u.id,
u.username,
COUNT(o.id) AS order_count, -- 下单次数
SUM(o.total_amount) AS total_spent -- 总消费金额
FROM
users u
INNER JOIN
orders o ON u.id = o.user_id
WHERE
o.created_at >= CURRENT_DATE - INTERVAL '30' DAY -- 最近30天
GROUP BY
u.id, u.username
HAVING
COUNT(o.id) >= 2 -- 至少下过2单
ORDER BY
total_spent DESC
LIMIT 20; -- 只看前20名
场景 2:检查数据库性能(查询慢查询或索引状态)
-- MySQL 查看当前运行的查询 SHOW FULL PROCESSLIST; -- 查看是否有表锁 (MySQL) SHOW OPEN TABLES WHERE In_use > 0; -- SQL Server 查看当前阻塞 SELECT * FROM sys.dm_exec_requests WHERE blocking_session_id != 0;
场景 3:数据清洗(查找重复数据)
-- 找出 email 重复的用户
SELECT
email,
COUNT(*) AS cnt
FROM
users
GROUP BY
email
HAVING
COUNT(*) > 1;
-- 删除重复数据(保留 ID 最小的那一条,谨慎操作)
DELETE FROM users
WHERE id NOT IN (
SELECT MIN(id)
FROM users
GROUP BY email
);
第四部分:最佳实践与注意事项
-
安全第一:不要直连生产库写脚本。
- 在测试数据库或只读副本上验证脚本正确性。
- 执行
UPDATE或DELETE语句前,先转成SELECT看一眼结果。
-
性能优化(索引与执行计划)。
WHERE子句中的列尽量有索引。- 避免在
WHERE中对列使用函数(如WHERE DATE(create_time) = '2023-01-01',应改为WHERE create_time >= '2023-01-01' AND create_time < '2023-01-02')。 - 使用
EXPLAIN命令(如EXPLAIN SELECT ...)查看查询执行计划,找出慢的原因。
-
可读性。
- SQL 关键字使用大写,表名/列名使用小写(团队约定)。
- 复杂查询使用 CTE(公用表表达式,
WITH子句)拆分逻辑。
-- 使用 CTE 的可读性更好 WITH active_users AS ( SELECT user_id, COUNT(*) as cnt FROM orders WHERE created_at > '2023-01-01' GROUP BY user_id HAVING cnt > 5 ) SELECT u.name, a.cnt FROM users u INNER JOIN active_users a ON u.id = a.user_id; -
参数化查询。
- 如果你在代码(如 Python、Java)中拼接查询字符串,务必使用参数占位符,防止 SQL 注入。
# Python 示例(错误做法) cursor.execute("SELECT * FROM users WHERE name = '" + name + "'") # Python 示例(正确做法) cursor.execute("SELECT * FROM users WHERE name = %s", (name,))
总结步骤
- 明确需求:我需要哪几张表的哪些列?筛选条件是什么?
- 从单表开始:先写
SELECT ... FROM ... WHERE ...跑通看数据对不对。 - 逐步加 JOIN:确认连接键(通常为主外键)是否正确。
- 加入聚合与排序:
GROUP BY后再ORDER BY。 - 调试与优化:
EXPLAIN检查性能,加索引。 - 安全上线:在非生产环境测试无误后,再在生产环境执行。
如果你有具体的数据库类型(如 MySQL 8.0 还是 PostgreSQL 15)或者特定的业务场景,可以告诉我,我能提供更精确的脚本示例。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播