目录
今天想查询身份证号是以奇数结尾和以偶数结尾的问题,随便看了一下网上的方法,大多都是下面情况:
查询奇数:
SELECT a.user_id
FROM t_user_info a
WHERE a.user_id&1 LIMIT 5
查询偶数:
SELECT a.user_id
FROM t_user_info a
WHERE a.user_id=(a.user_id>>1)<<1 LIMIT 5
方法解释:
查询奇数的方法 &1:
1的二进制是0001,与运算符:1 & 1 = 1, 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0;所以可以保证最后一位是奇数。
查询偶数的方法 字段=(字段>>1)<<1:
这是左移和右移运算符,先整除再乘,意思就是先整除2再乘以2,看前后结果是否一样,一样的就是偶数。
问题拓展(字符串):
但是这里面有个问题,就是这种方法是针对字段全是数字的情况,如果身份证号码中间用*号隐藏了一部分,就无法使用。
比如:
查询奇数:
SELECT a.idcard_num
FROM t_user_info a
WHERE a.idcard_num&1 LIMIT 5
查询偶数:
SELECT a.idcard_num
FROM t_user_info a
WHERE a.idcard_num=(a.idcard_num>>1)<<1
and a.idcard_num !=''
and a.idcard_num not like '%X'
order by a.idcard_num LIMIT 5
使用正则表达式解决:
查询奇数:
select a.idcard_num
from t_user_info a
where a.idcard_num regexp '[13579]$'
limit 5
查询偶数:
select a.idcard_num
from t_user_info a
where a.idcard_num regexp '[02468]$'
limit 5
这样更直接准确。
正则表达式补充介绍:
顺便说下正则表达式:
^aa :以 aa 为开头;
aa$ :以aa结尾;
. :匹配任何字符;
[abc]:[字符集合],包含中括号里的字符;
[^abc]:不包含中括号里的字符;
a|b|c :匹配a或b或c,(中|美)国;
* :匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,};
+ :匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,};
{n} :n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o;
{n,m} :m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。
相关案例:
比如:查找name字段中以元音字符开头或以'ok'字符串结尾的所有数据:
SELECT name
FROM person_tbl
WHERE name REGEXP '^[aeiou]|ok$';