2016-10-04 21 views
6

używam Presto. Mam pole ID, które jest numeryczne. Chcę kolumnę, która sumuje cyfry w id. Tak więc, jeśli id ​​= 1234, chce się kolumnę, która na wyjściu 10 t j 1 + 2 + 3 + 4.SQL zsumowanie cyfr z numeru

mogę użyć podciąg wyodrębnić każdą cyfrę i podsumować to, ale jest tam funkcja mogę używać lub prostszy sposób?

+0

może używać [ 'slice'] (https://prestodb.io/docs/current/functions/array.html) wygenerować tablicę, a następnie po prostu sumować wartości w tablicy? – xQbert

Odpowiedz

0

Jeśli czytam swoje pytanie poprawnie chcesz uniknąć konieczności hardcode chwycić podciągu dla każdej cyfry w identyfikatorze, jak substring (ID,1,1) + substring (ID,2,1) + ...substring (ID,n,1). Co jest nieeleganckie i działa tylko wtedy, gdy wszystkie twoje wartości ID i tak są tej samej długości.

Co można robić zamiast tego użyć rekurencyjnej CTE. Wykonanie tego w ten sposób działa również w przypadku pól ID o zmiennej długości.

Uwaga: Ten sposób nadal korzystać substring technicznie, ale to nie robi niezdarny hardcode chwycić

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

pierwszego użycia REGEXP_EXTRACT_ALL podzielić ciąg. Następnie użyj CROSS JOIN UNNEST GROUP BY do grupy wyodrębnione cyfry ich liczby oraz Podsumowując nad nimi.

Tutaj

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 
; 
1

Można łączyć regexp_extract_all od użytkownika @ akuhn odpowiedzieć lambda wsparcia niedawno dodanego do Presto. W ten sposób nie potrzebujesz unnest. Kod byłoby bardzo wymowne, jeśli nie potrzeba cast do iz 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) 
Powiązane problemy