MySQL常用SQL语法汇总_查询、更新、删除与数据操作详解

来源:这里教程网 时间:2026-02-28 19:35:45 作者:

mysql常用sql语法核心是数据查询、插入、更新与删除。1. 查询使用select,结合where条件、order by排序、limit限制结果数量;2. 插入用insert语句,支持单行、多行及从其他表导入;3. 更新用update配合where避免全表误改;4. 删除用delete并慎用where,truncate可快速清空表;5. 高效查询需理解数据模型、合理使用索引、优化join类型,避免对列使用函数影响性能;6. 更新与删除操作应始终使用where,结合事务确保安全,并分批处理大量数据;7. 实用技巧包括replace into实现存在即更新,insert ignore跳过重复项,on duplicate key update灵活upsert,以及case表达式处理条件逻辑。

MySQL常用SQL语法汇总_查询、更新、删除与数据操作详解

MySQL的常用SQL语法,核心围绕着数据的查询、插入、更新与删除。理解这些基础操作,是掌握数据库交互的关键,它不仅是数据库的语言,更是我们与数据对话的基石。

MySQL常用SQL语法汇总_查询、更新、删除与数据操作详解

解决方案

在我看来,掌握MySQL,首先得把这些“动词”玩溜:

数据查询 (SELECT)

MySQL常用SQL语法汇总_查询、更新、删除与数据操作详解

这是最常用的,没有之一。从简单的数据读取到复杂的数据聚合,全靠它。

基本查询:

MySQL常用SQL语法汇总_查询、更新、删除与数据操作详解
SELECT column1, column2 FROM table_name;
SELECT * FROM table_name; -- 查询所有列

条件查询 (WHERE):

SELECT column1, column2 FROM table_name WHERE condition;
-- 示例:
SELECT name, age FROM users WHERE age > 25 AND city = 'Beijing';

排序 (ORDER BY):

SELECT column1 FROM table_name ORDER BY column2 ASC|DESC;
-- 示例:
SELECT product_name, price FROM products ORDER BY price DESC;

限制结果数量 (LIMIT):

SELECT column1 FROM table_name LIMIT offset, count;
-- 示例:获取前10条记录
SELECT title FROM articles LIMIT 10;
-- 获取从第6条开始的5条记录 (offset从0开始)
SELECT title FROM articles LIMIT 5, 5;

聚合函数 (COUNT, SUM, AVG, MAX, MIN):

SELECT COUNT(*) FROM table_name;
SELECT AVG(price) FROM products WHERE category = 'Electronics';

分组 (GROUP BY) 与过滤分组 (HAVING):

SELECT category, COUNT(*) FROM products GROUP BY category HAVING COUNT(*) > 5;

连接查询 (JOIN): 这是处理多表关系的核心,也是初学者容易感到头疼的地方。

INNER JOIN (内连接): 只返回两个表中都匹配的行。
SELECT o.order_id, c.customer_name
FROM orders o INNER JOIN customers c ON o.customer_id = c.id;
LEFT JOIN (左连接): 返回左表所有行,以及右表匹配的行。如果右表没有匹配,则右表列显示NULL。
SELECT c.customer_name, o.order_id
FROM customers c LEFT JOIN orders o ON c.id = o.customer_id;
RIGHT JOIN (右连接): 返回右表所有行,以及左表匹配的行。
SELECT c.customer_name, o.order_id
FROM orders o RIGHT JOIN customers c ON o.customer_id = c.id;

数据插入 (INSERT)

把新数据塞进表里,就靠它了。

插入单行数据:

INSERT INTO table_name (column1, column2) VALUES (value1, value2);
-- 示例:
INSERT INTO users (name, age, email) VALUES ('张三', 30, 'zhangsan@example.com');

插入多行数据:

INSERT INTO table_name (column1, column2) VALUES (value1_a, value2_a), (value1_b, value2_b);
-- 示例:
INSERT INTO products (product_name, price) VALUES ('鼠标', 50), ('键盘', 120);

从另一个表插入数据:

INSERT INTO table_name1 (column1, column2) SELECT column_a, column_b FROM table_name2 WHERE condition;

数据更新 (UPDATE)

修改现有数据。这句操作得格外小心,尤其是

WHERE
子句,一个不留神就可能把整个表的数据都改错了。

更新数据:
UPDATE table_name SET column1 = new_value1, column2 = new_value2 WHERE condition;
-- 示例:
UPDATE users SET age = 31, city = 'Shanghai' WHERE name = '张三';

数据删除 (DELETE)

移除表中的数据。同样,

WHERE
子句是生命线,没有它,就是“删库跑路”的节奏。

删除数据:

DELETE FROM table_name WHERE condition;
-- 示例:
DELETE FROM products WHERE stock_quantity = 0;

删除所有数据 (TRUNCATE TABLE vs DELETE FROM):

TRUNCATE TABLE
DELETE FROM table_name
更快,因为它实际上是删除并重建了表,而不是逐行删除。但它不会触发DELETE触发器,并且无法回滚。

TRUNCATE TABLE table_name;

如何高效地进行复杂数据查询?

在日常开发中,我发现“高效”这个词在数据库查询里,往往意味着对数据结构和业务逻辑的深刻理解。仅仅是知道

JOIN
怎么写,或者
WHERE
后面能跟什么条件,这只是第一步。真正的挑战在于,当面对一个多表关联、数据量庞大、业务规则复杂的查询需求时,如何写出既准确又快速的SQL。

首先,理解你的数据模型至关重要。你得清楚哪些表之间有关系,通过哪个字段关联。比如,一个订单表(

orders
)和用户表(
users
),它们通常通过
user_id
关联。在构建
JOIN
时,明确你想要的结果集是基于哪个表的“全集”(比如
LEFT JOIN
),还是只想要两个表都有匹配项的交集(
INNER JOIN
)。我见过太多次,业务方觉得查询慢,结果一查SQL,发现是
LEFT JOIN
写成了
INNER JOIN
,或者反过来,导致结果集过大或不全。

其次,索引是性能的生命线。当你的

WHERE
子句、
JOIN
条件或者
ORDER BY
子句涉及的字段没有合适的索引时,数据库就不得不进行全表扫描,这在数据量大的时候简直是灾难。我通常会用
EXPLAIN
命令来分析SQL的执行计划,看看它是不是走了索引,有没有用到临时表或者文件排序。如果发现没有走索引,或者索引选择性不高,那就要考虑创建或优化索引了。但索引也不是越多越好,它会增加写入的开销,所以要权衡。

再者,子查询和派生表(Subquery and Derived Table)是处理复杂逻辑的利器。有时候,一个复杂的筛选条件需要先计算出一个中间结果集,再用这个结果集去过滤主查询。这时候,子查询就能派上用场。例如,查询那些购买了特定商品的用户,你可以先用一个子查询找出购买了该商品的所有用户ID,然后在外层查询中用

IN
或者
EXISTS
来过滤。派生表(即
FROM
子句中的子查询)则更灵活,可以预先聚合或筛选数据,再和其它表进行
JOIN
,这样能有效减少
JOIN
前的数据量,提高效率。我个人偏好在复杂场景下使用派生表,因为它通常比关联子查询更容易理解和优化。

最后,避免在

WHERE
子句中对列进行函数操作。比如
WHERE DATE(create_time) = '2023-01-01'
,这会导致索引失效,因为数据库无法直接利用索引树来查找函数处理后的值。正确的做法应该是
WHERE create_time >= '2023-01-01 00:00:00' AND create_time 。这种细节,往往是性能优化的关键点。

数据更新与删除操作有哪些安全注意事项?

数据更新和删除操作,在我看来,就像是数据库里的“高危作业”。一旦执行,数据的状态就可能永久改变,甚至丢失。所以,每次敲下

UPDATE
DELETE
,我心里都会默默念叨几句“阿弥陀佛”,然后反复确认。

最最核心的一点是:永远不要忘记

WHERE
子句! 这听起来像是老生常谈,但真实案例中,因为忘记
WHERE
而导致全表数据被更新或删除的事故,简直数不胜数。我个人就有过一次惊险经历,在测试环境里想更新几条数据,结果手一抖,
WHERE
条件没写全,差点把整个测试环境的数据都弄乱了。所以,每次写完
UPDATE
DELETE
语句,我都会习惯性地先看一眼
WHERE
,确认它是不是足够精确,是不是只会影响到我想要操作的那几条记录。如果是在生产环境,我甚至会先用
SELECT
语句把
WHERE
条件筛选出来的数据预览一遍,确保无误后再执行
UPDATE
DELETE

其次,事务(Transaction)是你的救星。在进行批量更新或删除操作时,尤其是在生产环境,务必使用事务。事务能保证一系列操作要么全部成功,要么全部失败回滚到操作前的状态。这意味着,即使在操作过程中发生错误(比如网络中断、程序崩溃),你也可以通过

ROLLBACK
命令将数据库恢复到初始状态,避免数据不一致或丢失。

START TRANSACTION; -- 开始一个事务
UPDATE products SET price = price * 1.10 WHERE category = 'Electronics';
DELETE FROM old_logs WHERE log_date < '2023-01-01';
-- 如果一切顺利,提交事务
COMMIT;
-- 如果发生错误或需要撤销,回滚事务
-- ROLLBACK;

我个人的习惯是,对于任何非单条、非测试环境的DML操作,都先用

START TRANSACTION
包起来,执行完
UPDATE
DELETE
后,先不急着
COMMIT
,而是再执行一遍
SELECT
确认结果是否符合预期,没问题了再
COMMIT
。这种谨慎,救过我好几次。

另外,使用

LIMIT
进行分批处理。对于需要更新或删除大量数据的场景,直接一次性操作可能会导致数据库锁表时间过长,甚至耗尽内存。这时候,可以考虑分批处理,每次只处理一部分数据。

-- 示例:分批删除旧日志
DELETE FROM large_log_table WHERE log_date < '2023-01-01' LIMIT 10000;
-- 然后循环执行,直到没有更多数据被删除

这种方式虽然需要更多的代码逻辑来控制循环,但能大大降低对数据库的压力,减少潜在的风险。

最后,备份永远是底线。无论你SQL写得多么完美,事务用得多么熟练,总有那么万分之一的可能性,事情会超出你的掌控。所以,在执行任何重要的DML操作之前,特别是涉及核心业务数据时,确保有最新的、可恢复的数据库备份。这就像是给自己买了一份保险,即便真的出了大问题,也能有条退路。

除了基本的增删改查,MySQL还有哪些实用的数据操作技巧?

除了我们每天都在用的

SELECT
INSERT
UPDATE
DELETE
,MySQL还提供了一些非常实用的数据操作技巧,它们在特定场景下能大大提升开发效率和代码的简洁性。在我看来,这些技巧就像是SQL语言中的“高级语法糖”,用好了能让你事半功倍。

一个我经常用到的,是

REPLACE INTO
。它其实是
DELETE
INSERT
的组合拳。如果你想插入一条数据,但又担心这条数据的主键或唯一索引已经存在,如果存在就更新,不存在就插入,那么
REPLACE INTO
就是你的不二之选。它会尝试插入新行,如果发现有唯一索引冲突,就会先删除旧行,再插入新行。这对于处理需要“存在即更新,不存在即插入”的业务逻辑非常方便。

REPLACE INTO users (id, name, age) VALUES (1, '李四', 28);
-- 如果id=1的用户已存在,则先删除该用户,再插入新数据;否则直接插入。

需要注意的是,

REPLACE INTO
在删除旧行时,会触发相关的删除触发器,并可能导致自增ID的跳跃。所以在使用时要清楚它的副作用。

另一个非常有用的技巧是

INSERT IGNORE
。顾名思义,它会尝试插入数据,但如果插入的数据导致唯一索引(包括主键)冲突,它会忽略这个错误,不插入新数据,也不会报错。这对于批量导入数据,而你又希望跳过重复项,而不是让整个导入过程失败时,特别有用。

INSERT IGNORE INTO products (product_id, product_name) VALUES (101, '新产品A'), (101, '重复产品B');
-- 第一条会成功插入,第二条因为product_id=101已存在而会被忽略,不会报错。

我个人觉得,

INSERT IGNORE
在数据清洗和去重导入的场景下表现出色,它能让你在面对“脏数据”时,不至于让整个程序崩溃。

再来就是

ON DUPLICATE KEY UPDATE
,这个比
REPLACE INTO
更灵活,也更符合“UPSERT”(更新或插入)的语义。当插入操作导致唯一索引冲突时,它不会删除旧行,而是直接更新旧行的指定字段。

INSERT INTO users (id, name, age) VALUES (2, '王五', 22)
ON DUPLICATE KEY UPDATE name = VALUES(name), age = VALUES(age);
-- 如果id=2的用户已存在,则更新其name和age字段;否则直接插入。
-- VALUES(name) 这里表示的是你尝试插入的那个name值。

这个语法在我处理用户配置、计数器更新等场景时,用得非常多。它避免了先查询再判断是插入还是更新的逻辑,直接一步到位,代码也更简洁。

最后,虽然不是直接的数据操作,但

CASE
表达式
SELECT
UPDATE
语句中进行条件逻辑判断时,能让SQL变得异常强大和灵活。它允许你在查询或更新时根据不同的条件返回不同的值。

SELECT
    product_name,
    price,
    CASE
        WHEN price > 100 THEN '高价'
        WHEN price BETWEEN 50 AND 100 THEN '中价'
        ELSE '低价'
    END AS price_level
FROM products;

这种内联的条件逻辑,能让你在数据库层面就完成一些业务逻辑的分类或转换,减少应用程序层的处理负担。我发现,学会灵活运用

CASE
,能让你的SQL语句在处理复杂业务逻辑时,变得更加优雅和高效。

相关推荐

热文推荐