PostgreSQL中如何实现将数字拆分为单独各位数字的SQL函数
拆分整数为单个数位集合的SQL实现
核心实现逻辑很直接:将输入数字转为字符串后逐位截取,再转回数字类型,按原有顺序组装为数组/结果集即可,以下是不同主流数据库的可直接复用的实现:
MySQL 8.0+ 版本
如果需要直接返回数组格式的结果,可创建如下自定义函数:
DELIMITER // CREATE FUNCTION split_num(num BIGINT) RETURNS JSON DETERMINISTIC BEGIN DECLARE num_str VARCHAR(20) DEFAULT CAST(num AS CHAR); DECLARE str_len INT DEFAULT CHAR_LENGTH(num_str); DECLARE idx INT DEFAULT 1; DECLARE result JSON DEFAULT JSON_ARRAY(); -- 逐位遍历字符串拼接结果 WHILE idx <= str_len DO SET result = JSON_ARRAY_APPEND(result, '$', CAST(SUBSTRING(num_str, idx, 1) AS UNSIGNED)); SET idx = idx + 1; END WHILE; RETURN result; END // DELIMITER ;
调用验证:执行SELECT split_num(78912346);会返回[7, 8, 9, 1, 2, 3, 4, 6],符合预期。
如果不需要封装函数,要直接返回逐位数字的行集,可以用递归CTE实现:
WITH RECURSIVE cte AS ( SELECT 1 AS pos, CAST(78912346 AS CHAR) AS num_str UNION ALL SELECT pos + 1, num_str FROM cte WHERE pos < CHAR_LENGTH(num_str) ) SELECT CAST(SUBSTRING(num_str, pos, 1) AS UNSIGNED) AS digit FROM cte ORDER BY pos;
PostgreSQL 版本
PostgreSQL原生支持数组操作和序列生成,函数实现更简洁:
CREATE OR REPLACE FUNCTION split_num(num BIGINT) RETURNS INT[] AS $$ SELECT ARRAY( SELECT SUBSTRING(CAST(num AS TEXT) FROM i FOR 1)::INT FROM generate_series(1, CHAR_LENGTH(CAST(num AS TEXT))) i ORDER BY i ); $$ LANGUAGE SQL IMMUTABLE;
调用验证:执行SELECT split_num(78912346);会直接返回你需要的{7,8,9,1,2,3,4,6}格式结果。
SQL Server 版本
SQL Server的表值函数实现如下,调用后可直接获取逐位数字的结果集:
CREATE FUNCTION split_num(@num BIGINT) RETURNS @result TABLE (pos INT IDENTITY(1,1), digit INT) AS BEGIN DECLARE @num_str VARCHAR(20) = CAST(@num AS VARCHAR(20)); DECLARE @idx INT = 1; WHILE @idx <= LEN(@num_str) BEGIN INSERT INTO @result(digit) VALUES (CAST(SUBSTRING(@num_str, @idx, 1) AS INT)); SET @idx = @idx + 1; END RETURN; END;
调用方式:SELECT digit FROM split_num(78912346) ORDER BY pos;即可按原顺序拿到所有数位。
补充说明:如果业务场景中输入可能包含负数,拆分前先取绝对值即可,避免负号被当做字符处理;如果需要拆分带小数的数字,逻辑完全一致,转字符串后逐位截取时跳过小数点即可。
内容的提问来源于stack exchange,提问作者mikasa
相关产品推荐
相关产品推荐

