1. 基本查询示例
sql
-- 假设表名为 users,身份证字段名为 id_card
SELECT
id_card,
SUBSTRING(id_card, 17, 1) AS 第17位, -- 截取第17位
CASE
WHEN CAST(SUBSTRING(id_card, 17, 1) AS INT) % 2 = 1
THEN '男'
ELSE '女'
END AS 性别
FROM users
WHERE LEN(id_card) = 18; -- 确保是18位身份证
2. 完整函数封装
sql
-- 创建判断性别的函数
CREATE FUNCTION dbo.GetGenderByIdCard(@id_card VARCHAR(18))
RETURNS VARCHAR(2)
AS
BEGIN
DECLARE @gender VARCHAR(2)
IF LEN(@id_card) <> 18 OR ISNUMERIC(SUBSTRING(@id_card, 1, 17)) = 0
RETURN '无效' -- 身份证格式不正确
IF CAST(SUBSTRING(@id_card, 17, 1) AS INT) % 2 = 1
SET @gender = '男'
ELSE
SET @gender = '女'
RETURN @gender
END
使用函数:
sql
SELECT id_card, dbo.GetGenderByIdCard(id_card) AS 性别
FROM users
3. 包含15位和18位身份证的判断
sql
SELECT
id_card,
CASE
WHEN LEN(id_card) = 15 THEN -- 15位旧身份证
CASE
WHEN CAST(SUBSTRING(id_card, 15, 1) AS INT) % 2 = 1
THEN '男'
ELSE '女'
END
WHEN LEN(id_card) = 18 THEN -- 18位新身份证
CASE
WHEN CAST(SUBSTRING(id_card, 17, 1) AS INT) % 2 = 1
THEN '男'
ELSE '女'
END
ELSE '格式错误'
END AS 性别
FROM users
注意事项
-
异常处理:在实际使用时需要确保截取的字符是数字
-
性能优化:如果数据量较大,可以添加索引
-
数据验证:应先验证身份证格式是否正确
sql
-- 更安全的查询(处理可能的非数字情况)
SELECT
id_card,
CASE
WHEN ISNUMERIC(SUBSTRING(id_card, 17, 1)) = 1
THEN CASE
WHEN CAST(SUBSTRING(id_card, 17, 1) AS INT) % 2 = 1
THEN '男'
ELSE '女'
END
ELSE '未知'
END AS 性别
FROM users
WHERE LEN(id_card) = 18;
提取年龄等其他信息(扩展)
sql
-- 提取出生日期和计算年龄
SELECT
id_card,
CASE
WHEN LEN(id_card) = 18
THEN CONVERT(DATE, SUBSTRING(id_card, 7, 8))
WHEN LEN(id_card) = 15
THEN CONVERT(DATE, '19' + SUBSTRING(id_card, 7, 6))
END AS 出生日期,
DATEDIFF(YEAR,
CONVERT(DATE,
CASE
WHEN LEN(id_card) = 18
THEN SUBSTRING(id_card, 7, 8)
WHEN LEN(id_card) = 15
THEN '19' + SUBSTRING(id_card, 7, 6)
END
),
GETDATE()
) AS 年龄
FROM users