如何在T-SQL中总结字符的char代码?

时间:2018-04-19 09:42:51

标签: c# sql tsql

我需要对字符串的最后6个符号的char代码求和。 我可以通过C#总结最后6个字符,如下所示:

string str = "helloWorld";
var sumLastSixCharacters = str.Where((ch, i) => (i > 3) ).Sum(x => x); //631

我已经编写了以下代码来总结最后6个字符,但在我看来, 应该有更优雅的解决方案:

DECLARE @Foo VARCHAR(10);
SET @Foo='helloWorld';

SELECT   
    CASE WHEN TRY_CONVERT(BIGINT, @Foo) IS NULL   
    THEN ASCII(SUBSTRING(@Foo, 5,1)) + ASCII(SUBSTRING(@Foo, 6,1)) + 
        ASCII(SUBSTRING(@Foo, 7,1)) + ASCII(SUBSTRING(@Foo, 8,1)) + 
        ASCII(SUBSTRING(@Foo, 9,1)) + ASCII(SUBSTRING(@Foo, 10,1)) 
    ELSE 'Cast succeeded'  
END AS Result; 

伙计们,有谁知道如何以更好的方式计算最后6个字符的总和?

2 个答案:

答案 0 :(得分:2)

这样做了。我修改了它来解决原来的问题。

对我来说,我需要一个函数来评估连接字段以查找重复的模式,例如: ABC |工商银行 和 cba | ABC

我现在可以找到这些实例并用另一个替换一个,所以现在我只有 ABC | cba

使用 SELECT database_of_your_choice.dbo.CREATE_STRING_CHECKSUM('yourstringhere') 调用它

--代码如下

use database_of_your_choice
go

CREATE FUNCTION dbo.CREATE_STRING_CHECKSUM
(
    @string nvarchar(100) = NULL
)
RETURNS int
AS
BEGIN
    
    DECLARE @pos int = 0,
            @len int = len(@string),
            @ascii_sum int = 0,
            @iter_count int = 6

    --just in case you pass a string with less than 6 characters
    if(@iter_count > @len) set @iter_count=@len

    --loops for @iter_count: 6 times
    while @iter_count > 0 begin
        --passing @len to SUBSTRING will look at the right-most char decremented
        --with each iteration: get the right most 6 characters
        set @ascii_sum += ASCII(substring(@string,@len,1))
        set @len -= 1
        set @iter_count -= 1
    end 

    -- Return the result of the function
    RETURN @ascii_sum

END
GO

答案 1 :(得分:1)

您可以对反向字符串使用递归CTE

DECLARE @str VARCHAR(100)='helloWorld';

WITH recCTE AS
(
    SELECT REVERSE(@str) AS OriginalReversed
          ,1 AS Position
          ,SUBSTRING(REVERSE(@str),1,1) AS CharAtPos
    UNION ALL
    SELECT r.OriginalReversed
          ,r.Position +1
          ,SUBSTRING(r.OriginalReversed,r.Position+1,1)
    FROM recCTE AS r
    WHERE Position<6 --specify the character count here
)
/*
--Use this to see the intermediate result
SELECT * 
FROM recCTE
*/
SELECT SUM(ASCII(CharAtPos)) --631
FROM recCTE;

一些解释

CTE将采用反向输入,开始1并取第一个字符(从结尾开始)。

然后它向下迭代,将位置增加1以读取下一个字符。

这样您就可以将test转换为

t
s
e
t

SUM值使用ASCII是您需要的结果

更新

总结ASCII值可能是一个坏主意......任何具有相同字符的单词都会导致相同的结果......

如果你只需要从字符串中获取一个数字,你可以使用它:

DECLARE @str VARCHAR(100)='helloWorld';
SELECT CAST(CAST(RIGHT(@str,6) AS BINARY(6)) AS BIGINT)

这将只取6字节的二进制块并将其解释为BIGINT