SQL汇总数字的数字

时间:2016-10-04 19:25:48

标签: sql presto

我正在使用presto。我有一个数字的ID字段。我想要一个列在id中的数字。因此,如果ID = 1234,我想要一个输出10的列,即1 + 2 + 3 + 4。

我可以使用子字符串来提取每个数字并对其求和,但是有一个我可以使用的函数还是更简单的方法?

3 个答案:

答案 0 :(得分:1)

您可以将@ akuhn的答案regexp_extract_all与最近添加到Presto的lambda支持结合起来。这样你就不需要unnest了。如果不需要cast来自varchar,那么代码将非常自我解释:

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)

答案 1 :(得分: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

答案 2 :(得分: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
;