Суммируйте цифры в столбце, чтобы получить одно число

Как я могу написать оператор SQL (SQL Server), который сможет создать столбец B, который будет содержать сумму цифр в столбце A. Например:

Значение столбца A = 12345
Значение столбца B = 1+2+3+4+5 = 15

Я мог бы попробовать функцию Left пару раз, а затем разделить каждую цифру в отдельном столбце, а затем суммировать эти столбцы.

К, ребята Спасибо за ваши усилия дать совет: Я понял, что это утверждение отлично работает для меня, потому что значения в столбце, в котором я должен суммировать цифры, никогда не превысят более 10 из них. Поскольку мой вычисляемый столбец - это все, что мне нужно для достижения этой цели. Я много работал с Excel и мог не видеть вещи как программисты SQL, для меня этот код работает.

SELECT '1234567'
    , convert(integer,left('1234567',1))
    + convert(integer,right(left('1234567',2),1))
    + convert(integer,right(left('1234567',iif (len('1234567') >= 3, 3, 0)),1))
    + convert(integer,right(left('1234567',iif (len('1234567') >= 4, 4, 0)),1))
    + convert(integer,right(left('1234567',iif (len('1234567') >= 5, 5, 0)),1)) 
    + convert(integer,right(left('1234567',iif (len('1234567') >= 6, 6, 0)),1))
    + convert(integer,right(left('1234567',iif (len('1234567') >= 7, 7, 0)),1))
    + convert(integer,right(left('1234567',iif (len('1234567') >= 8, 8, 0)),1))
    + convert(integer,right(left('1234567',iif (len('1234567') >= 9, 9, 0)),1))
    + convert(integer,right(left('1234567',iif (len('1234567') >= 10, 10, 0)),1))

Какое значение имеет столбец A?

Dale K 16.06.2023 22:42

Задавая вопрос, вы должны предоставить минимальный воспроизводимый пример: (1) DDL и выборочное заполнение данных, т. е. таблицы CREATE плюс операторы INSERT T-SQL. (2) Что вам нужно сделать, т. е. логика и ваш код попытаются реализовать ее в T-SQL. (3) Желаемый результат, основанный на примерных данных в # 1 выше. (4) Ваша версия SQL Server (SELECT @@version;).

Yitzhak Khabinsky 16.06.2023 22:49

Привет, спасибо за ваш совет.

Daniel Moniak 17.06.2023 15:32
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
90
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

На самом деле это не сильная сторона SQL Server, но вы можете сделать что-то вроде этого:

declare @data table (i bigint)

insert into @data 
values  (12345)
,   (100000000009)
,   (3333)

;with cte as (
    select cast(row_number() over(order by @@spid) as int) AS sort
    from (
    values (1), (2), (3), (4),(5)
    ) x(x)
    cross apply (
        values(1),(2),(3),(4),(5),(30)
        ) y(y)
    )
select *
from @data d
cross apply (
    select sum(num) as total
    from (
        select cast(substring(cast(d.i as nvarchar(30)), c.sort, 1) as int) as num
        from cte c
        where c.sort <= LEN(d.i)
        ) x
    ) y

Я создаю небольшую таблицу серий в CTE между 1 и 30, а затем по одной подстроке каждого символа из числа и суммирую их в APPLY.

В более новых версиях вы можете использовать GENERATE_SERIES, чтобы пропустить CTE.

Ответ принят как подходящий

Пожалуйста, попробуйте следующее решение.

SQL №1

-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY KEY, digits VARCHAR(20));
INSERT @tbl (digits) VALUES
('12345'),
('1234567890');
-- DDL and sample data population, end

SELECT id, digits, result = SUM(TRY_CAST(SUBSTRING(digits, number, 1) AS INT))
FROM @tbl CROSS APPLY
(
    SELECT DISTINCT number
    FROM master..spt_values
    WHERE number BETWEEN 1 and LEN(digits)
) V
GROUP BY id, digits;

SQL №2

-- SQL Server 2022 onwards
SELECT id, digits, result = SUM(TRY_CAST(SUBSTRING(digits, value, 1) AS INT))
FROM @tbl 
    CROSS APPLY GENERATE_SERIES(1, LEN(digits))
GROUP BY id, digits;

Выход

идентификатор цифры результат 1 12345 15 2 1234567890 45

Привет, я много работал с Excel и мог не видеть вещи как программисты SQL, для меня этот код работал, потому что мне не нужно больше, чем проверить до 10 цифр:

Daniel Moniak 17.06.2023 15:34

Хороший ответ включает объяснение в дополнение к рабочему коду.

Dale K 18.06.2023 01:19

@DanielMoniak, рад слышать, что предложенные решения работают на вас. Пожалуйста, не забудьте отметить его как ответ. Щелкните зеленую галочку слева от ответа, который решил вашу проблему. Это помечает ответ как «принятый».

Yitzhak Khabinsky 18.06.2023 03:12

Ниже приведено то, что вы можете рассмотреть — довольно простое, но с преимуществом, которое вы можете легко добавить в качестве простого вычисляемого столбца, если это необходимо; вы можете без проблем использовать здесь substring, если вы ссылаетесь на несуществующую позицию символа.

Предположим, что ваш исходный столбец имеет тип int - если это будет varchar или char, то внутреннее преобразование будет избыточным, и, возможно, вам может понадобиться try_convert с isnull, если есть какая-либо возможность нечисловых данных.

В зависимости от ваших исходных данных вы можете добавить или удалить количество элементов подстроки.

with t as ( /*sample table*/ 
  select 12345 as col union all
    select 123 union all
    select 456789
)
select 
      convert(tinyint, Substring(convert(char(6), col), 1, 1))
    + convert(tinyint, Substring(convert(char(6), col), 2, 1))
    + convert(tinyint, Substring(convert(char(6), col), 3, 1))
    + convert(tinyint, Substring(convert(char(6), col), 4, 1))
    + convert(tinyint, Substring(convert(char(6), col), 5, 1))
    + convert(tinyint, Substring(convert(char(6), col), 6, 1))
from t;
create table mydata (N bigint);

insert into mydata
(N)
values  
(12345),
(999999),
(123456789);

используйте следующий запрос

SELECT a.N
    ,sum(cast(substring(a.b, v.number + 1, 1) AS INT)) Result
FROM (
    SELECT N
        ,cast(N AS NVARCHAR(max)) b
    FROM mydata
    ) a
INNER JOIN master..spt_values v ON v.number < len(a.b)
WHERE v.type = 'P'
GROUP BY a.N

дбфиддл

Хороший ответ включает объяснение в дополнение к рабочему коду

Dale K 18.06.2023 01:18

Другие вопросы по теме