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


На самом деле это не сильная сторона 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;
Выход
Привет, я много работал с Excel и мог не видеть вещи как программисты SQL, для меня этот код работал, потому что мне не нужно больше, чем проверить до 10 цифр:
Хороший ответ включает объяснение в дополнение к рабочему коду.
@DanielMoniak, рад слышать, что предложенные решения работают на вас. Пожалуйста, не забудьте отметить его как ответ. Щелкните зеленую галочку слева от ответа, который решил вашу проблему. Это помечает ответ как «принятый».
Ниже приведено то, что вы можете рассмотреть — довольно простое, но с преимуществом, которое вы можете легко добавить в качестве простого вычисляемого столбца, если это необходимо; вы можете без проблем использовать здесь 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
Хороший ответ включает объяснение в дополнение к рабочему коду
Какое значение имеет столбец A?