SQL(Structured Query Language)作为关系型数据库的核心交互语言,自1974年由IBM研究员提出以来,已成为数据领域最通用的标准语言。根据DB-Engines的最新统计,SQL在数据库查询语言中的使用占比超过83%,其重要性不言而喻。本文将系统讲解SQL的基础语法体系,帮助读者构建坚实的数据操作基础。
-- 基础查询
SELECT employee_id, name, department
FROM employees;
-- 别名与去重
SELECT DISTINCT department AS dept
FROM employees;
-- 全字段查询(慎用)
SELECT * FROM products;
SELECT语句的执行顺序:
-- 标准插入
INSERT INTO customers (name, email, created_at)
VALUES ('张三', '[email protected]', NOW());
-- 多行插入(提升性能)
INSERT INTO products (name, price)
VALUES
('鼠标', 99.00),
('键盘', 199.00),
('显示器', 899.00);
-- 从其他表导入
INSERT INTO archive_orders
SELECT * FROM orders
WHERE order_date < '2020-01-01';
-- 基础更新
UPDATE employees
SET salary = salary * 1.05
WHERE performance_rating >= 4;
-- 多字段更新
UPDATE products
SET
price = price * 0.9,
stock = stock - 10
WHERE product_id = 1005;
-- 使用子查询更新
UPDATE customer_stats
SET total_orders = (
SELECT COUNT(*)
FROM orders
WHERE customer_id = 123
)
WHERE customer_id = 123;
-- 条件删除
DELETE FROM log_records
WHERE create_date < '2023-01-01';
-- 全表删除(危险操作)
TRUNCATE TABLE temp_data; -- 更快且不可回滚
-- 级联删除示例
DELETE FROM departments
WHERE department_id = 5
CASCADE CONSTRAINTS;
SELECT * FROM products
WHERE
price > 100 AND price <= 500
OR category = '电子产品';
执行顺序:NOT > AND > OR
建议使用括号明确优先级:
SELECT * FROM employees
WHERE (department = '销售部' OR department = '市场部')
AND salary > 8000;
-- BETWEEN包含边界值
SELECT * FROM orders
WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';
-- IN子查询优化
SELECT * FROM customers
WHERE region IN ('华东', '华南', '华北');
-- NULL值处理
SELECT * FROM contacts
WHERE phone_number IS NOT NULL;
-- 通配符扩展:
-- _ 匹配单个字符
-- % 匹配任意长度字符
-- [] 指定字符范围(部分数据库支持)
SELECT * FROM documents
WHERE filename LIKE '报告_2023%';
-- 全文索引优化(MySQL示例)
SELECT * FROM articles
WHERE MATCH(content) AGAINST('数据库优化');
SELECT product_name, category, price
FROM products
ORDER BY
category ASC,
price DESC,
stock_count ASC;
-- MySQL分页
SELECT * FROM user_logs
ORDER BY log_time DESC
LIMIT 20 OFFSET 40; -- 第3页(每页20条)
-- SQL Server分页
SELECT TOP 20 *
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY sales DESC) AS row_num,
*
FROM sales_records
) AS temp
WHERE row_num > 40;
-- 分页优化建议:
-- 1. 避免深度分页(OFFSET过大)
-- 2. 使用覆盖索引
-- 3. 记录最后位置法
函数 | 描述 | 特殊处理 |
---|---|---|
COUNT(*) | 统计行数 | 包含NULL |
COUNT(col) | 统计非NULL值 | |
AVG() | 平均值 | 自动忽略NULL |
SUM() | 求和 | 非数值返回NULL |
MAX/MIN | 极值 | 可处理日期 |
-- 基础分组
SELECT
department,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
-- 多级分组
SELECT
YEAR(order_date) AS order_year,
QUARTER(order_date) AS order_quarter,
SUM(amount) AS total_sales
FROM orders
GROUP BY
YEAR(order_date),
QUARTER(order_date);
-- ROLLUP扩展(生成小计)
SELECT
category,
sub_category,
SUM(sales)
FROM products
GROUP BY ROLLUP(category, sub_category);
SELECT
customer_id,
COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5
AND MAX(order_amount) > 1000;
-- 与WHERE对比执行顺序
SELECT
department,
AVG(salary) avg_salary
FROM employees
WHERE hire_date > '2020-01-01' -- 先过滤
GROUP BY department
HAVING AVG(salary) > 8000; -- 后过滤分组
SELECT
u.region,
DATE_FORMAT(o.order_date, '%Y-%m') AS month,
COUNT(DISTINCT o.user_id) AS active_users,
SUM(o.amount) AS total_sales,
AVG(o.amount) AS avg_order_value
FROM orders o
JOIN users u ON o.user_id = u.user_id
WHERE o.status = 'completed'
AND o.order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY
u.region,
DATE_FORMAT(o.order_date, '%Y-%m')
HAVING SUM(o.amount) > 100000
ORDER BY
u.region ASC,
month DESC
LIMIT 100;
性能优化原则:
安全防护要点:
# 避免SQL注入示例(Python)
cursor.execute(
"SELECT * FROM users WHERE username = %s AND password = %s",
(username, password_hash)
)
可维护性建议:
执行顺序:WHERE在分组前过滤行,HAVING在分组后过滤组
可用字段:WHERE不能使用聚合函数,HAVING可以
性能影响:优先使用WHERE减少处理数据量
现代数据库优化器对两者处理相同,但COUNT(col)会跳过NULL值
LIMIT是MySQL/PostgreSQL语法,TOP是SQL Server语法,建议使用标准OFFSET-FETCH
通过本文的系统讲解,读者应该已经掌握了SQL的基础语法框架。建议的学习路径:
后续可继续深入: