如何在SQL

时间:2017-03-17 21:47:13

标签: sql sql-server

我正在编写一个大致具有这种结构的查询:

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,以便我可以转换并维护正确的顺序。此列仅用于排序。

感谢您的帮助!

2 个答案:

答案 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