-- 创建用户表CREATE TABLE IF NOT EXISTS users ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 新增一列ALTER TABLE users ADD COLUMN age TINYINT UNSIGNED;-- 删除列ALTER TABLE users DROP COLUMN email;-- 重命名表RENAME TABLE users TO accounts;-- 通过表查询创建表DROP TABLE IF EXISTS company_in_out_label_tmp;create table company_in_out_label_tmp asselect *from data_center.t_company_changesWHERE project_name = "地址变更(住所地址、经营场所、驻在地址等变更)" and credit_code != ''
如何为导入数据创建表格
表中数据的增删改(DML)
操作
常用语句
关键点
增(插入行)
INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2); INSERT INTO 表名 SET 列1=值1, 列2=值2; INSERT INTO 表名 SELECT ...;
单行插入或多行:VALUES (...), (...), (...);REPLACE INTO 会在主键/唯一键冲突时先删除旧行再插入。 INSERT ... ON DUPLICATE KEY UPDATE 冲突时执行更新。 insert into ... select ... 利用查询数据进行插入数据。
删(删除行)
DELETE FROM 表名 WHERE 条件;
必须慎用:不加 WHERE 会删除全部行! 删除全表用 TRUNCATE TABLE 表名; 更快,且重置自增计数器(不可回滚)。 - TRUNCATE 与 DELETE 区别:TRUNCATE 不记日志、不可回滚、重置自增列,DELETE 可加条件、触发触发器、逐行记录日志。 有表连接时需要指明要删除的表: DELETE 表1, 表2 — 删除哪几张表的记录 FROM 表1 JOIN 表2 ON 条件 [WHERE 条件];
改(更新行)
UPDATE 表名 SET 列1 = 值1, 列2 = 值2 WHERE 条件;
必须带 WHERE,否则全表更新。 可结合 ORDER BY 和 LIMIT 控制更新行数。 更新单表:(左连接时没有匹配的字段会视为Null) UPDATE 表1 JOIN 表2 ON 表1.关联字段 = 表2.关联字段 SET 表1.要更新的字段 = 新值 WHERE 条件; 更新多表: UPDATE 表1 JOIN 表2 ON 条件 SET 表1.字段 = 值1, 表2.字段 = 值2 WHERE …;
-- 插入单行INSERT INTO users (username, age) VALUES ('张三', 28);-- 批量插入INSERT INTO users (username, age) VALUES('李四', 25),('王五', 30);-- 插入查询结果INSERT INTO vip_users SELECT * FROM users WHERE age > 28;INSERT INTO hxnew_center.com_base (unifiedSocialCreditCode,companyName,listImportDate)select t1.credit_code,t1.comp_name,CURDATE()from (select * from data_center.t_company_base WHERE biz_date = (select max(biz_date) from data_center.t_company_base WHERE credit_code != '') and credit_code != '') t1left join hxnew_center.com_base t2WHERE t2.unifiedSocialCreditCode is NULL;-- 删除一条记录DELETE FROM users WHERE id = 10;-- 更新指定用户的年龄UPDATE users SET age = 29 WHERE username = '张三';-- 如果希望保留左表所有行,即使右表没有匹配(没有匹配的字段会视为 NULL)UPDATE orders oLEFT JOIN customers c ON o.customer_id = c.idSET o.discount = IF(c.level = 'VIP', 0.1, 0);-- 删除没有订单的客户DELETE cFROM customers cLEFT JOIN orders o ON c.id = o.customer_idWHERE o.id IS NULL;
日期时间处理
MySQL 提供了丰富的日期时间函数,可以灵活地进行获取、提取、运算、格式化和转换。下面按功能分类总结,并附上常用的计算场景和示例。
GROUP_CONCAT([DISTINCT] expr ORDER BY … SEPARATOR …)
行转列,将分组内的值拼接成一个字符串
SELECT CONCAT('Hello', ' ', 'World'); -- Hello WorldSELECT CONCAT_WS('-', '2026', '05', '26'); -- 2026-05-26SELECT GROUP_CONCAT(DISTINCT city ORDER BY city SEPARATOR '/') FROM users;
-- MySQL 8.0+SELECT REGEXP_SUBSTR(address, '[0-9]+(?=号楼)') AS building_no FROM houses;-- 5.7 简易方式:截取“号楼”前的部分再处理(受限)SELECT SUBSTRING_INDEX(address, '号楼', 1) AS prefix FROM houses;-- 再提取末尾数字较为复杂
5. 判断字符串是否包含某子串
-- 返回 1 表示包含SELECT LOCATE('admin', user_name) > 0 AS is_admin FROM users;-- 或用 REGEXPSELECT user_name REGEXP 'admin' FROM users;
6. 逗号分隔字段查询(多值匹配)
-- 表中 tags 列存储 'a,b,c',查询包含 'b' 的记录SELECT * FROM articles WHERE FIND_IN_SET('b', tags);
如果 ORDER BY 的列是字符串类型(如 VARCHAR)但存的是数字,排序会按字典序而不是数值大小。
-- num_str 列值:'1','10','2','20'SELECT num_str FROM t ORDER BY num_str; -- '1','10','2','20' (字典序)SELECT num_str FROM t ORDER BY CAST(num_str AS UNSIGNED); -- '1','2','10','20'
4. 常用业务场景中的类型转换
4.1 将存储为字符串的数字用于数值排序或计算
-- 正确排序SELECT * FROM products ORDER BY CAST(price_str AS DECIMAL(10,2));-- 计算总和SELECT SUM(CAST(amount_str AS UNSIGNED)) FROM payments;
4.2 数字补零 / 格式化
-- 订单编号:'ORD' + 6位流水号SELECT CONCAT('ORD', LPAD(CAST(id AS CHAR), 6, '0')) AS order_noFROM orders;-- 如果 id 是数字,LPAD 会隐式转为字符串
4.3 提取字符串中的数字并转换为数值
-- MySQL 8.0 正则提取并转换SELECT CAST(REGEXP_SUBSTR('楼层15-16室', '[0-9]+') AS UNSIGNED) AS floor;-- 结果为 15
4.4 安全处理空值或无效值
-- 如果字段可能为 NULL 或非数字,计算时给默认值SELECT IFNULL(CAST(score AS SIGNED), 0) FROM exams;-- 或者用 CASE 判断SELECT CASE WHEN score REGEXP '^[0-9]+$' THEN CAST(score AS SIGNED) ELSE 0 ENDFROM exams;
4.5 判断字符串能否转为日期,并转换
-- 尝试转为日期,如果失败则返回 NULLSELECT IF(STR_TO_DATE(date_str, '%Y-%m-%d') IS NULL, NULL, CAST(date_str AS DATE))FROM raw_data;-- 或者直接用 STR_TO_DATESELECT STR_TO_DATE(date_str, '%Y-%m-%d') FROM raw_data; -- 无法转换返回 NULL
4.6 JSON 字段值提取并转换类型
SELECT JSON_UNQUOTE(JSON_EXTRACT(extra, '$.age')) AS age_str, CAST(JSON_UNQUOTE(JSON_EXTRACT(extra, '$.age')) AS UNSIGNED) AS age_intFROM profiles;-- MySQL 5.7.8+ 也可使用 ->> 操作符SELECT extra->>'$.age' AS age_str, CAST(extra->>'$.age' AS UNSIGNED) AS age_intFROM profiles;
4.7 字符串比较忽略大小写(通过字符集转换实现)
SELECT * FROM users WHERE CONVERT(username USING utf8mb4) = 'admin';-- 或者使用 COLLATE,更规范
4.8 二进制与字符串互转
-- 字符串转二进制(如存储哈希值)SELECT UNHEX(SHA2('hello', 256));-- 二进制转可读字符串SELECT HEX(binary_field) FROM t;
4.9 避免隐式转换带来的”诡异”结果
-- 错误:'a' 被转为 0,导致 WHERE 条件为真SELECT * FROM t WHERE 0 = 'a'; -- 返回所有行!-- 正确做法:使用 CAST 或显式类型确保类型一致SELECT * FROM t WHERE CAST(col AS UNSIGNED) = 0;
总结要点
类型判断多借助 REGEXP、ISNULL、STR_TO_DATE 等函数来间接实现。
显式转换使用 CAST(expr AS type) 或 CONVERT(expr, type),可使代码清晰、避免隐式陷阱。