SQL 求一个数各位数字之和

6
我正在使用Presto。我有一个数字ID字段。我想要一个列,它将ID中的数字相加。因此,如果ID = 1234,则我想要一个输出10的列,即1 + 2 + 3 + 4。
我可以使用substring提取每个数字并将其相加,但是否有可用的函数或更简单的方法?

也许可以使用 slice 生成一个数组,然后简单地对数组中的值求和? - xQbert
3个回答

2
您可以将 @akuhn 的答案中的 regexp_extract_all 与 Presto 最近添加的 lambda 支持结合起来使用。这样,您就不需要使用 unnest。如果不需要进行 varcharcast,则代码将非常易于理解和自我解释。
presto> select
    reduce(
        regexp_extract_all(cast(x as varchar), '\d'), -- split into digits array
        0, -- initial reduction element
        (s, x) -> s + cast(x as integer), -- reduction function
        s -> s -- finalization
    ) sum_of_digits
from (values 1234) t(x);

 sum_of_digits
---------------
            10
(1 row)

0
如果我正确理解了你的问题,你想避免为ID中的每个数字硬编码一个子字符串提取,比如substring(ID,1,1)+ substring(ID,2,1) + ...substring(ID,n,1)。这种方法不够优雅,并且仅适用于所有ID值长度相同的情况。
您可以使用递归CTE来代替。这种方法也适用于具有可变值长度的ID字段。
免责声明:这仍然在技术上使用了substring,但它不会进行笨拙的硬编码提取。
WITH recur (ID, place, ID_sum)
AS
(
    SELECT ID, 1 , CAST(substring(CAST(ID as varchar),1,1) as int)
    FROM SO_rbase
UNION ALL
    SELECT ID, place + 1, ID_sum + substring(CAST(ID as varchar),place+1,1)  
    FROM recur
    WHERE len(ID) >= place + 1
)

SELECT ID, max(ID_SUM) as ID_sum
FROM recur
GROUP BY ID

0

首先使用REGEXP_EXTRACT_ALL来分割字符串。然后使用CROSS JOIN UNNEST GROUP BY按照数字将提取出的数字进行分组,并对它们求和。

在这里,

WITH my_table AS (SELECT * FROM (VALUES ('12345'), ('42'), ('789')) AS a (num))
SELECT 
    num, 
    SUM(CAST(digit AS BIGINT)) 
FROM 
    my_table
CROSS JOIN 
    UNNEST(REGEXP_EXTRACT_ALL(num,'\d')) AS b (digit) 
GROUP BY 
    num
;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接