我正在编写一个大致具有这种结构的查询:
SELECT Name, <calculated-valued> as Version FROM <tables>
这个计算出的值需要这样工作:我有一个varchar列'Name',可能包含类似'ABC'的东西,我想将每个字母转换成ASCII,并将它们重新附加在一起形成'65 .66.67'在这个例子中。 (空字符串应返回'0')有没有办法做到这一点?
我的方法不是很好,但我最多可以做5个字符:
SELECT
CASE WHEN LEN(Name) = 0 THEN '0'
ELSE CAST(ASCII(SUBSTRING(Name, 1, 1)) as varchar(max)) +
CASE WHEN LEN(Name) = 1 THEN ''
ELSE '.' + CAST(ASCII(SUBSTRING(Name, 2, 1)) as varchar(max)) +
CASE WHEN LEN(Name) = 2 THEN ''
ELSE '.' + CAST(ASCII(SUBSTRING(Name, 3, 1)) as varchar(max)) +
CASE WHEN LEN(Name) = 3 THEN ''
ELSE '.' + CAST(ASCII(SUBSTRING(Name, 4, 1)) as varchar(max)) +
CASE WHEN LEN(Name) = 4 THEN ''
ELSE '.' + CAST(ASCII(SUBSTRING(Name, 5, 1)) as varchar(max))
END
END
END
END
END AS MyColumn
FROM <tables>
有更好的方法吗?理想情况下,一个方法可以采用任何长度的字符串?
或者我可以将字母转换为hierarchyid数据类型吗?我需要创建像1/2 / a / bc / 4 //等等的东西,但hierarchyid不支持。所以相反,我试图将其转换为1/2/97 / 98.99 / 4/0,以便我可以转换并维护正确的顺序。此列仅用于排序。
感谢您的帮助!
答案 0 :(得分:0)
一种方法是递归CTE:
with cte as (
select Name, 1 as lev
cast(ascii(substring(name, 1, 1)) as varchar(max)) as ascii_name
from t
union all
select Name, lev + 1,
ascii_name + '.' + cast(ascii(substring(name, lev + 1, 1)) as varchar(max))
from cte
where len(Name) > lev
)
select Name, ascii_name
from cte;
答案 1 :(得分:0)
另一个选项是ad-hoc计数表和CROSS APPLY
Declare @YourTable table (Name varchar(25))
Insert Into @YourTable values
('ABC'),
('Jack'),
('Jill'),
('')
Select A.Name
,Version = isnull(B.String,'0')
From @YourTable A
Cross Apply (
Select String=Stuff((Select '.' +cast(S as varchar(5))
From (Select Top (len(A.Name))
S=ASCII(substring(A.Name,Row_Number() Over (Order By (Select NULL)),1))
From master..spt_values ) S
For XML Path ('')),1,1,'')
) B
返回
Name String
ABC 65.66.67
Jack 74.97.99.107
Jill 74.105.108.108
0