题目描述
在contacts表中存储用户联系信息,需查询符合以下条件的电话号码,按id升序输出所有字段:
- 电话号码的数字部分共10位,且第一位不能以0开头;
- 格式支持两种:
- 连续10位数字(如
1234567890); - 固定分隔格式(3-3-4结构,如
123-456-7890)。
- 连续10位数字(如
题目分析
本题核心是电话号码的格式校验,需同时满足数字长度、首位规则、格式规则三个条件:
- 数字长度:无论是否分隔,数字部分必须为10位。
- 首位规则:10位数字的第一位不能为0。
- 格式规则:需精准匹配“连续10位”或“3-3-4 分隔”两种模式。
难点在于高效区分格式,并确保字符符合规则。
解法一:字符串函数组合(LEFT+LENGTH+LIKE)
这种方法适合不会用正则表达式的小伙伴~
select *
from contacts
where left(phone_number, 1) in ("1", "2", "3", "4", "5", "6", "7", "8", "9")
and (length(phone_number) = 10
or phone_number like "___-___-____")
order by id asc;
代码关键点
- 首位校验:
通过
LEFT(phone_number, 1)提取首位字符,判断其是否为1-9(排除0开头的非法情况)。 - 长度与格式校验:
length(phone_number) = 10:匹配连续10位数字。phone_number like "___-___-____":匹配 3-3-4 分隔格式(两个减号固定位置,使用占位符_分别表示前3位、中间3位、后4位)。
这个解法的缺点是没有办法完全排除电话号码中间有字母的情况,但可以解决本题的测试用例。
解放二(进阶版):正则表达式(REGEXP)
select *
from contacts
where phone_number regexp "^[1-9]([0-9]{9}|[0-9]{2}-[0-9]{3}-[0-9]{4})$"
order by id asc;
代码关键点
- 正则语法解析:
正则通过分支匹配(
|表示 “或”)覆盖两种格式:- 分支1(连续数字格式):
^[1-9][0-9]{9}$^标记字符串开头,$标记字符串结尾;[1-9]匹配首位(非0),[0-9]{9}匹配后续9位数字。
- 分支 2(分隔格式):
^[1-9][0-9]{2}-[0-9]{3}-[0-9]{4}$- 前3位:
[0-9]{2}匹配前2位(结合首位共3位); - 中间3位:
[0-9]{3}匹配中间3位; - 后4位:
[0-9]{4}匹配最后4位。
- 前3位:
- 分支1(连续数字格式):
- 正则表达总结:
^标记字符串开头,$标记字符串结尾;[1-9]表示范围,{}为数量符,表示有几位;|表示“或”,可用()圈起来,逻辑更严谨。
- 优势与局限:
- 正则表达式更严谨,但语法较复杂;字符串函数更直观,适合简单场景。

京公网安备 11010502036488号