常用SQL整理

常用SQL整理
一.单表查询
1.基础查询

sql 复制代码
-- 查询所有列
SELECT * FROM table_name;

-- 查询指定列
SELECT column1, column2, column3 FROM table_name;

-- 查询表达式和别名
SELECT column1, column2 * 2 AS double_col FROM table_name;

-- 去重查询
SELECT DISTINCT column1 FROM table_name;

-- 排序查询,支持多列排序
SELECT * FROM table_name ORDER BY column1 ASC, column2 DESC;

-- 分页查询(MySQL)
SELECT * FROM table_name ORDER BY id LIMIT 10 OFFSET 20;

-- 分页查询(SQL Server)
SELECT * FROM table_name ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

-- 查询别名
SELECT column1 AS alias1, column2 AS alias2 FROM table_name;

2.数据过滤

sql 复制代码
-- 等值过滤
SELECT * FROM table_name WHERE column1 = 'value';

-- 多条件过滤(AND、OR)
SELECT * FROM table_name WHERE column1 = 'value' AND (column2 > 10 OR column3 IS NULL);

-- 模糊匹配
SELECT * FROM table_name WHERE column1 LIKE '%abc%';

-- 正则匹配(MySQL)
SELECT * FROM table_name WHERE column1 REGEXP '^abc';

-- 范围查询
SELECT * FROM table_name WHERE column2 BETWEEN 10 AND 20;

-- 空值判断
SELECT * FROM table_name WHERE column3 IS NULL;
SELECT * FROM table_name WHERE column3 IS NOT NULL;

-- IN和NOT IN
SELECT * FROM table_name WHERE column1 IN ('a', 'b', 'c');
SELECT * FROM table_name WHERE column1 NOT IN ('a', 'b', 'c');

-- EXISTS子查询
SELECT * FROM table_name t WHERE EXISTS (SELECT 1 FROM other_table o WHERE o.id = t.id);

-- 复杂条件示例
SELECT * FROM table_name WHERE (column1 = 'a' OR column1 = 'b') AND column2 BETWEEN 5 AND 10;

3.聚合函数

sql 复制代码
-- 计数
SELECT COUNT(*) FROM table_name;
SELECT COUNT(DISTINCT column1) FROM table_name;

-- 求和、平均、最大、最小
SELECT SUM(column2), AVG(column2), MAX(column2), MIN(column2) FROM table_name;

-- 分组统计
SELECT column1, COUNT(*) AS cnt, AVG(column2) AS avg_val FROM table_name GROUP BY column1;

-- 分组过滤(HAVING)
SELECT column1, COUNT(*) AS cnt FROM table_name GROUP BY column1 HAVING cnt > 5;

-- GROUP BY ROLLUP(分组汇总)
SELECT column1, column2, SUM(column3) FROM table_name GROUP BY ROLLUP(column1, column2);

4.高级窗口函数

sql 复制代码
-- 行号
SELECT column1, ROW_NUMBER() OVER (ORDER BY column2 DESC) AS rn FROM table_name;

-- 排名
SELECT column1, RANK() OVER (ORDER BY column2 DESC) AS rnk FROM table_name;

-- 密集排名
SELECT column1, DENSE_RANK() OVER (ORDER BY column2 DESC) AS drnk FROM table_name;

-- 累计和
SELECT column1, SUM(column2) OVER (ORDER BY column3 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_sum FROM table_name;

-- 分区排名
SELECT column1, RANK() OVER (PARTITION BY column3 ORDER BY column2 DESC) AS partition_rank FROM table_name;

二.多表查询

1.表连接操作

sql 复制代码
-- 内连接
SELECT a.*, b.* FROM table_a a INNER JOIN table_b b ON a.id = b.a_id;

-- 左连接
SELECT a.*, b.* FROM table_a a LEFT JOIN table_b b ON a.id = b.a_id;

-- 右连接
SELECT a.*, b.* FROM table_a a RIGHT JOIN table_b b ON a.id = b.a_id;

-- 全连接(部分数据库支持)
SELECT a.*, b.* FROM table_a a FULL OUTER JOIN table_b b ON a.id = b.a_id;

-- 自连接
SELECT a1.*, a2.* FROM table_a a1 JOIN table_a a2 ON a1.parent_id = a2.id;

-- 交叉连接
SELECT a.*, b.* FROM table_a a CROSS JOIN table_b b;

2.子查询

sql 复制代码
-- 标量子查询
SELECT column1, (SELECT MAX(column2) FROM table_b) AS max_val FROM table_a;

-- IN子查询
SELECT * FROM table_a WHERE id IN (SELECT a_id FROM table_b);

-- EXISTS子查询
SELECT * FROM table_a WHERE EXISTS (SELECT 1 FROM table_b WHERE table_b.a_id = table_a.id);

-- 相关子查询
SELECT * FROM table_a a WHERE column1 > (SELECT AVG(column1) FROM table_a WHERE category = a.category);

-- 子查询作为表
SELECT a.*, b.total FROM table_a a JOIN (SELECT a_id, COUNT(*) AS total FROM table_b GROUP BY a_id) b ON a.id = b.a_id;

3.联合查询

sql 复制代码
-- UNION去重
SELECT column1 FROM table_a UNION SELECT column1 FROM table_b;

-- UNION ALL不去重
SELECT column1 FROM table_a UNION ALL SELECT column1 FROM table_b;

-- ORDER BY排序
SELECT column1 FROM table_a UNION ALL SELECT column1 FROM table_b ORDER BY column1 DESC;

三.常用函数

1.字符串处理

sql 复制代码
-- 拼接字符串
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM table_name;

-- 字符串长度
SELECT LENGTH(column1) FROM table_name;  -- MySQL
SELECT LEN(column1) FROM table_name;     -- SQL Server

-- 子串截取
SELECT SUBSTRING(column1, 1, 5) FROM table_name;

-- 大小写转换
SELECT LOWER(column1), UPPER(column1) FROM table_name;

-- 去空格
SELECT TRIM(column1) FROM table_name;

-- 替换字符串
SELECT REPLACE(column1, 'old', 'new') FROM table_name;

-- 查找字符串位置
SELECT INSTR(column1, 'sub') FROM table_name;  -- MySQL
SELECT CHARINDEX('sub', column1) FROM table_name; -- SQL Server

2.时间日期函数

sql 复制代码
-- 当前时间
SELECT NOW();          -- MySQL
SELECT GETDATE();      -- SQL Server

-- 日期提取
SELECT YEAR(date_col), MONTH(date_col), DAY(date_col) FROM table_name;

-- 日期加减
SELECT DATE_ADD(date_col, INTERVAL 7 DAY) FROM table_name;  -- MySQL
SELECT DATE_SUB(date_col, INTERVAL 1 MONTH) FROM table_name;

SELECT DATEADD(DAY, 7, date_col) FROM table_name;           -- SQL Server
SELECT DATEADD(MONTH, -1, date_col) FROM table_name;

-- 日期差
SELECT DATEDIFF(day, '2023-01-01', '2023-01-10');           -- SQL Server
SELECT DATEDIFF('day', '2023-01-01', '2023-01-10');         -- PostgreSQL

-- 格式化日期
SELECT DATE_FORMAT(date_col, '%Y-%m-%d') FROM table_name;   -- MySQL
SELECT FORMAT(date_col, 'yyyy-MM-dd') FROM table_name;      -- SQL Server

四.常用操作

1.数据操作

sql 复制代码
-- 插入
INSERT INTO table_name (col1, col2) VALUES ('val1', 123);

-- 批量插入
INSERT INTO table_name (col1, col2) VALUES ('v1', 1), ('v2', 2);

-- 更新
UPDATE table_name SET col1 = 'new_val' WHERE id = 10;

-- 删除
DELETE FROM table_name WHERE id = 10;

-- 清空表
TRUNCATE TABLE table_name;

2.表操作

sql 复制代码
-- 创建表
CREATE TABLE table_name (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    age INT DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 添加列
ALTER TABLE table_name ADD COLUMN email VARCHAR(255);

-- 修改列类型
ALTER TABLE table_name MODIFY COLUMN age SMALLINT;

-- 重命名列
ALTER TABLE table_name RENAME COLUMN old_name TO new_name;

-- 删除列
ALTER TABLE table_name DROP COLUMN email;

-- 删除表
DROP TABLE table_name;

-- 重命名表
RENAME TABLE old_table TO new_table;

3.约束与索引

sql 复制代码
-- 添加主键
ALTER TABLE table_name ADD PRIMARY KEY (id);

-- 添加唯一约束
ALTER TABLE table_name ADD UNIQUE (column1);

-- 添加外键
ALTER TABLE table_name ADD CONSTRAINT fk_name FOREIGN KEY (column2) REFERENCES other_table(id);

-- 创建索引
CREATE INDEX idx_name ON table_name(column1);

-- 创建唯一索引
CREATE UNIQUE INDEX idx_unique_name ON table_name(column1);

-- 删除索引
DROP INDEX idx_name ON table_name;

4.视图

sql 复制代码
-- 创建视图
CREATE VIEW view_name AS SELECT col1, col2 FROM table_name WHERE col3 > 100;

-- 查询视图
SELECT * FROM view_name;

-- 更新视图
CREATE OR REPLACE VIEW view_name AS SELECT col1, col2 FROM table_name WHERE col3 > 200;

-- 删除视图
DROP VIEW view_name;

5.事务控制

sql 复制代码
BEGIN TRANSACTION;  -- 开始事务
COMMIT;             -- 提交事务
ROLLBACK;           -- 回滚事务

SAVEPOINT sp1;      -- 设置保存点
ROLLBACK TO sp1;    -- 回滚到保存点

6.权限管理

sql 复制代码
GRANT SELECT, INSERT ON db.table TO 'user'@'host';
REVOKE INSERT ON db.table FROM 'user'@'host';
SHOW GRANTS FOR 'user'@'host';

四.其他操作
1.数据库管理

sql 复制代码
-- 创建数据库
CREATE DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 删除数据库
DROP DATABASE database_name;

-- 查看当前数据库
SELECT DATABASE();

-- 切换数据库
USE database_name;

-- 查看所有数据库
SHOW DATABASES;

-- 查看当前连接用户
SELECT USER();

-- 查看当前连接信息
SELECT CONNECTION_ID();

2. 表结构与元数据查询

sql 复制代码
-- 查看表结构(字段、类型、默认值等)
DESCRIBE table_name;
SHOW COLUMNS FROM table_name;

-- 查看表的创建语句
SHOW CREATE TABLE table_name;

-- 查看表大小(MySQL)
SELECT table_name, 
       ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'database_name' AND table_name = 'table_name';

-- 查看所有表
SHOW TABLES;

-- 查看表的索引信息
SHOW INDEX FROM table_name;

-- 查看表的约束信息(MySQL 8+)
SELECT * FROM information_schema.table_constraints WHERE table_name = 'table_name';

3. 性能监控与优化

sql 复制代码
-- 查看当前运行的查询(MySQL)
SHOW PROCESSLIST;

-- 查看慢查询日志(需开启慢查询日志)
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';

-- EXPLAIN查询计划
EXPLAIN SELECT * FROM table_name WHERE column1 = 'value';

-- ANALYZE查询计划(部分数据库支持)
ANALYZE SELECT * FROM table_name WHERE column1 = 'value';

-- 优化表(MySQL)
OPTIMIZE TABLE table_name;

-- 修复表(MySQL)
REPAIR TABLE table_name;

4. 数据备份与恢复

sql 复制代码
-- MySQL备份整个数据库(命令行)
mysqldump -u username -p database_name > backup.sql

-- 备份指定表
mysqldump -u username -p database_name table_name > table_backup.sql

-- 备份结构不含数据
mysqldump -u username -p -d database_name > structure_backup.sql

-- 备份数据不含结构
mysqldump -u username -p -t database_name > data_backup.sql

-- 恢复数据库
mysql -u username -p database_name < backup.sql

5. 数据导入导出

sql 复制代码
-- 导出查询结果到CSV(MySQL)
SELECT * INTO OUTFILE '/tmp/result.csv'
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM table_name;

-- 从CSV导入数据(MySQL)
LOAD DATA INFILE '/tmp/result.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;  -- 忽略表头

-- SQL Server导出数据
bcp database_name.schema.table_name out datafile.csv -c -t, -S servername -U username -P password

-- SQL Server导入数据
bcp database_name.schema.table_name in datafile.csv -c -t, -S servername -U username -P password

6. 事务与锁管理

sql 复制代码
-- 查看当前锁信息(MySQL)
SHOW ENGINE INNODB STATUS;

-- 查看当前事务
SELECT * FROM information_schema.innodb_trx;

-- 查看锁等待
SELECT * FROM information_schema.innodb_lock_waits;

-- 设置事务隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 查看当前隔离级别
SELECT @@tx_isolation;

-- 显示锁定的表
SHOW OPEN TABLES WHERE In_use > 0;

7. 用户与权限管理

sql 复制代码
-- 创建用户(MySQL)
CREATE USER 'username'@'host' IDENTIFIED BY 'password';

-- 删除用户
DROP USER 'username'@'host';

-- 授权权限
GRANT SELECT, INSERT, UPDATE ON database_name.* TO 'username'@'host';

-- 撤销权限
REVOKE UPDATE ON database_name.* FROM 'username'@'host';

-- 查看用户权限
SHOW GRANTS FOR 'username'@'host';

-- 修改用户密码
ALTER USER 'username'@'host' IDENTIFIED BY 'new_password';

-- 刷新权限
FLUSH PRIVILEGES;

8. 系统信息查询

sql 复制代码
-- 查看服务器版本
SELECT VERSION();

-- 查看当前时间
SELECT NOW();

-- 查看当前连接数
SHOW STATUS LIKE 'Threads_connected';

-- 查看最大连接数
SHOW VARIABLES LIKE 'max_connections';

-- 查看字符集
SHOW VARIABLES LIKE 'character_set%';

-- 查看排序规则
SHOW VARIABLES LIKE 'collation%';

9. 临时表与变量

sql 复制代码
-- 创建临时表
CREATE TEMPORARY TABLE temp_table AS SELECT * FROM table_name WHERE 1=0;

-- 插入临时表
INSERT INTO temp_table SELECT * FROM table_name WHERE column1 = 'value';

-- 使用变量(MySQL)
SET @var_name = 100;
SELECT @var_name;

-- 变量在查询中使用
SELECT * FROM table_name WHERE id > @var_name;

10. 存储过程与函数

sql 复制代码
-- 创建存储过程(MySQL示例)
DELIMITER //
CREATE PROCEDURE GetUserCount(OUT userCount INT)
BEGIN
    SELECT COUNT(*) INTO userCount FROM users;
END //
DELIMITER ;

-- 调用存储过程
CALL GetUserCount(@count);
SELECT @count;

-- 创建函数
DELIMITER //
CREATE FUNCTION GetDiscount(price DECIMAL(10,2)) RETURNS DECIMAL(10,2)
BEGIN
    DECLARE discount DECIMAL(10,2);
    SET discount = price * 0.9;
    RETURN discount;
END //
DELIMITER ;

-- 使用函数
SELECT GetDiscount(100);

11. 触发器

sql 复制代码
-- 创建触发器(MySQL示例)
CREATE TRIGGER before_insert_user
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
    SET NEW.created_at = NOW();
END;

-- 删除触发器
DROP TRIGGER before_insert_user;

12. 备份与恢复自动化脚本示例(Linux Shell)

sql 复制代码
#!/bin/bash
# 自动备份MySQL数据库

DATE=$(date +%F)
BACKUP_DIR="/backup/mysql"
DB_NAME="your_database"
USER="your_user"
PASS="your_password"

mkdir -p $BACKUP_DIR/$DATE

mysqldump -u $USER -p$PASS $DB_NAME > $BACKUP_DIR/$DATE/$DB_NAME.sql

# 删除7天前备份
find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} \;

总结优化方式:
1. 索引优化
1.1 合理使用索引

选择性高的列建索引,避免低选择性列(如性别)单独建索引。

联合索引按查询条件顺序创建,遵循最左前缀原则。

覆盖索引:索引包含查询所需所有列,避免回表。

sql 复制代码
-- 创建联合索引(列顺序重要)
CREATE INDEX idx_name ON table_name(col1, col2);

-- 使用覆盖索引示例
SELECT col1, col2 FROM table_name WHERE col1 = 'value';

1.2 避免索引失效

避免对索引列进行函数操作或隐式类型转换。

避免在索引列上使用<>, NOT IN, IS NULL等导致全表扫描的操作。

避免OR条件导致索引失效,改用UNION。

sql 复制代码
-- 不要这样,索引失效
SELECT * FROM table WHERE DATE(col_date) = '2023-01-01';

-- 改写为
SELECT * FROM table WHERE col_date >= '2023-01-01' AND col_date < '2023-01-02';

2. 查询重写

*2.1 避免SELECT **

明确列出需要查询的字段,减少IO和网络传输。

sql 复制代码
-- 不推荐
SELECT * FROM orders WHERE status = 'completed';

-- 推荐
SELECT order_id, customer_id, order_date FROM orders WHERE status = 'completed';

2.2 使用 EXISTS 替代 IN

对于子查询,EXISTS通常比IN性能更好,尤其是子查询结果大时。

sql 复制代码
-- IN 子查询
SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM orders);

-- EXISTS 子查询
SELECT * FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);

2.3 避免不必要的DISTINCT

DISTINCT会增加排序开销,确认是否真的需要去重。
2.4 使用JOIN代替子查询

子查询有时性能较差,改用JOIN提高效率。

sql 复制代码
-- 子查询
SELECT name FROM customers WHERE id IN (SELECT customer_id FROM orders WHERE amount > 100);

-- JOIN
SELECT DISTINCT c.name FROM customers c JOIN orders o ON c.id = o.customer_id WHERE o.amount > 100;

3. 执行计划分析

使用EXPLAIN查看SQL执行计划,重点关注:

是否使用索引(key列)

扫描行数(rows列)

连接类型(type列,最好是ref、const,避免ALL)

是否有临时表和文件排序

sql 复制代码
EXPLAIN SELECT * FROM orders WHERE customer_id = 123;

根据执行计划调整索引和SQL结构。
4. 分区表优化

大表使用分区(按范围、列表、哈希)减少单次扫描数据量。

查询时利用分区裁剪,提升查询效率。

sql 复制代码
-- MySQL范围分区示例
CREATE TABLE orders (
    order_id INT,
    order_date DATE,
    amount DECIMAL(10,2)
)
PARTITION BY RANGE (YEAR(order_date)) (
    PARTITION p2019 VALUES LESS THAN (2020),
    PARTITION p2020 VALUES LESS THAN (2021),
    PARTITION pmax VALUES LESS THAN MAXVALUE
);

5. 物化视图(Materialized View)

预计算复杂查询结果,减少实时计算压力。

支持定期刷新。

sql 复制代码
-- Oracle示例
CREATE MATERIALIZED VIEW mv_sales_summary
REFRESH FAST ON COMMIT
AS
SELECT product_id, SUM(amount) total_amount FROM sales GROUP BY product_id;

6. 并行查询

利用数据库并行执行能力,提升大数据量查询性能。

需配置数据库参数支持。

sql 复制代码
-- Oracle示例
SELECT /*+ parallel(t,4) */ * FROM large_table t WHERE condition;

7. 缓存利用

利用数据库缓存机制,避免频繁访问磁盘。

通过合理设计SQL和索引,提升缓存命中率。
8. 避免大事务和长事务

大事务会占用大量锁资源,影响并发。

拆分大事务,减少锁等待。
9. 参数化查询与预编译

避免SQL注入,提高执行效率。

sql 复制代码
-- 伪代码示例
PREPARE stmt FROM 'SELECT * FROM users WHERE id = ?';
EXECUTE stmt USING @user_id;

10. 统计信息及时更新

保证优化器有准确统计信息,避免错误执行计划。

sql 复制代码
-- MySQL
ANALYZE TABLE table_name;

-- Oracle
EXEC DBMS_STATS.GATHER_TABLE_STATS('schema', 'table_name');

11. 示例综合优化

sql 复制代码
-- 原始查询(可能全表扫描)
SELECT * FROM orders WHERE DATE(order_date) = '2023-01-01' AND status = 'completed';

-- 优化后
SELECT order_id, customer_id, amount FROM orders
WHERE order_date >= '2023-01-01' AND order_date < '2023-01-02' AND status = 'completed'
AND status = 'completed'
AND customer_id IN (SELECT customer_id FROM customers WHERE vip_flag = 1);

12. 其他实用技巧

复制代码
避免SELECT DISTINCT + ORDER BY,改用GROUP BY。
避免使用NOT IN,改用LEFT JOIN IS NULL或NOT EXISTS。
避免函数索引列,改写为范围查询。
合理使用覆盖索引,减少回表。
避免过多JOIN,拆分复杂查询。
使用批量插入替代多条单条插入。
合理设置连接池和缓存参数。
相关推荐
blackA_22 分钟前
数据库MySQL学习——day4(更多查询操作与更新数据)
数据库·学习·mysql
极限实验室1 小时前
Easysearch 迁移数据之 Reindex From Remote
数据库
朴拙数科1 小时前
基于LangChain与Neo4j构建企业关系图谱的金融风控实施方案,结合工商数据、供应链记录及舆情数据,实现隐性关联识别与动态风险评估
数据库·langchain·neo4j
小李学不完2 小时前
Oracle--SQL事务操作与管理流程
数据库
qq_441996052 小时前
为何 RAG 向量存储应优先考虑 PostgreSQL + pgvector 而非 MySQL?
数据库·mysql·postgresql
Ivan陈哈哈2 小时前
Redis是单线程的,如何提高多核CPU的利用率?
数据库·redis·缓存
小光学长3 小时前
基于vue框架的电信用户业务管理系统的设计与实现8ly70(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库
程序员不想YY啊3 小时前
MySQL元数据库完全指南:探秘数据背后的数据
数据库·mysql·oracle
数据最前线3 小时前
Doris表设计与分区策略:让海量数据管理更高效
数据库
时光追逐者3 小时前
MongoDB从入门到实战之MongoDB快速入门(附带学习路线图)
数据库·学习·mongodb