我正在尝试在SQL中创建一个while循环,它看起来有点复杂。这就是我需要它实现的目标:
在遍历整个字符串之后,这应返回由上述过程生成的数值。
这是我到目前为止所做的,但我现在已经陷入困境(不用说,这段代码还没有用,但我想我正朝着正确的方向前进):
: m_data(rhs.data)
PS。输入将始终为100%数字值,但在我收到它时将其格式化为VARCHAR。
更新
样本字符串的预期结果是15
答案 0 :(得分:3)
您可以在不使用循环的情况下执行此操作。这是使用Tally Table的解决方案:
DECLARE @x VARCHAR(20) = '12345'
DECLARE @z INT = 0 -- base value
;WITH E1(N) AS( -- 10 ^ 1 = 10 rows
SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
CteTally(N) AS(
SELECT TOP(LEN(@x)) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
FROM E4
),
CteChars(N, num) AS(
SELECT
t.N, CAST(SUBSTRING(@x, t.N, 1) AS INT)
FROM CteTally t
WHERE t.N <= LEN(@x)
)
SELECT
SUM(
CASE
WHEN N % 2 = 0 THEN num
WHEN num * 2 < 10 THEN num * 2
ELSE (num * 2) - 9
END
) + @z
FROM CteChars
CTE
最多CteTally
生成一个从1到LEN(@x)
的数字列表。 CteChars
逐个字符地将@x
分成不同的行。然后,最终SELECT
根据条件执行SUM
。
OUTPUT : 15
答案 1 :(得分:2)
检查下面是否有帮助
DECLARE @x varchar(20) = '12345'
DECLARE @p int = 1
DECLARE @result bigint=0;
DECLARE @tempval int =0;
WHILE @p <= len(@x)
BEGIN
SET @tempval = CONVERT(INT,substring(@x, @p, 1));
if(@p%2 = 1)
BEGIN
SET @tempval = @tempval * 2;
IF(@tempval >= 10) SET @tempval = @tempval - 9;
END
SET @result = @result + @tempval;
SET @p = @p + 1;
END;
PRINT @result;--This is the result
RETURN @x;
答案 2 :(得分:1)
DECLARE @x INT = 12345
DECLARE @p int = len(@x)
DECLARE @z INT =0
PRINT @p%2
SET @x=@x/10
PRINT @x
WHILE @p > 0
BEGIN
IF(@p%2 = 0)
BEGIN
SET @z=@z+@x%10
SET @p=@p-1
SET @x=@x/10
END
ELSE
BEGIN
SET @z=@z+(2*(@x%10))
SET @p=@p-1
SET @x=@x/10
IF(@x>=10)
BEGIN
SET @x=(@x/10+@x%10)
END
END
END
SELECT @z
答案 3 :(得分:1)
这里似乎没有必要使用while循环。 这可以通过CTE分割字符串和case语句来实现:
DECLARE @x varchar(20) = '12345';
with split(id, v) as (
select 0, cast(0 as tinyint)
union all
select id+1, cast(SUBSTRING(@x, id+1, 1) as tinyint)
From split
Where id+1 <= len(@x)
)
Select Result = SUM(
Case When id % 2 = 0 then v
When v < 5 then v*2
Else (v*2)-9
End
)
From split
输出= 15