4. 风控用户表手机号格式校验
任务说明
对风控用户表 risk_user 中的 phone 字段做格式校验:合法手机号应为 11 位纯数字(以 1 开头)。输出所有不符合该格式的用户 user_id 与 phone,便于后续清洗或人工复核。
环境与依赖
- MySQL 5.7+ / 8.0(使用
REGEXP与CHAR_LENGTH)。 - 目标表:
risk_user(user_id, phone),phone为字符串类型(VARCHAR)。
建表与样例数据
CREATE TABLE risk_user (
user_id BIGINT PRIMARY KEY,
phone VARCHAR(32)
);
INSERT INTO risk_user (user_id, phone) VALUES
(1001, '13800138000'), -- 合法
(1002, '1380013800'), -- 10 位,非法
(1003, '138001380000'), -- 12 位,非法
(1004, '23800138000'), -- 非 1 开头,非法
(1005, '1380013800a'), -- 含字母,非法
(1006, NULL), -- 空值,非法
(1007, '138 0013 8000'); -- 含空格,非法
校验 SQL
核心思路:用 REGEXP '^1[0-9]{10}$' 同时约束“以 1 开头 + 共 11 位数字”,再用 NOT 取反;NULL 不满足正则,需用 OR phone IS NULL 显式纳入非法集合。
SELECT user_id, phone
FROM risk_user
WHERE phone IS NULL
OR phone NOT REGEXP '^1[0-9]{10}$';
运行与验证
- 执行上面的建表与插入语句,再执行校验 SQL。
- 预期返回 6 行:
1002、1003、1004、1005、1006、1007,即除1001外的全部记录。 - 判定通过条件:结果集恰好包含上述 6 个
user_id,且不含1001。
常见问题
- 若
phone为数值类型,前导 0 或超长会被截断,建议统一存为 VARCHAR。 - MySQL 8.0 可用
REGEXP_LIKE(phone, '^1[0-9]{10}$')替代REGEXP,语义一致。 - 若需兼容国际号码,应放宽正则并单独维护国家码规则,不要直接复用本校验。