SQL Server拆分字符串并访问它的不同部分

时间:2018-01-02 05:21:21

标签: sql sql-server

我需要更新存储在列中的网址。

我的列的值如下:

https://www.site.sharepoint.com/sites/test/AB-19-CALL

我想将此网址更新为:

https://www.site.sharepoint.com/sites/test/CALL-AB-19

要获取AB-19-CALL的最后一部分,我使用了以下查询

SELECT 
    SUBSTRING(urlcompte, LEN(urlcompte) - CHARINDEX('/', REVERSE(urlcompte)) + 2, LEN(urlcompte)), 
    UrlCompte 
FROM 
    tblAccount

现在要拆分和反转AB-19-call我再次需要使用上面的整个查询,然后使用-选择子字符串

有更简单的方法吗?

在C#中,我们可以这样做:

urlCompte.Split('-')[2] + urlCompte.Split('-')[0] + urlCompte.Split('-')[1] 

SQL Server中是否有一种方法可以拆分列并访问其中的不同部分?

4 个答案:

答案 0 :(得分:2)

这可以分割字符串部分 -

DECLARE @txt NVARCHAR(500)= 'https://www.site.sharepoint.com/sites/test/AB-19-CALL';

SELECT value
FROM STRING_SPLIT(REVERSE(SUBSTRING(REVERSE(@txt), 1, CHARINDEX('/', REVERSE(@txt))-1)), '-');(substring(reverse(@txt),1,charindex('/',reverse(@txt))-1)),'-')

答案 1 :(得分:2)

如果你很幸运能够使用SQL Server 2017,那么你可以使用string_agg function来连接与SQL string_split function拼凑的分割字符串

以下是更改网址中最后一部分顺序的脚本

declare @url varchar(100) = 'CALL-AB-19'

select 
    string_agg(value,'-') within group (order by rn desc) 
from (
    select 
        value, row_number() over (order by @url) as rn 
    from STRING_SPLIT( @url , '-' )
) t

如果要将此解决方案作为基于集合的解决方案应用于具有单个SELECT语句的表行,则可以执行以下SQL

select 
    id, string_agg(value,'-') within group (order by rn desc) 
from (
    select 
        id, value, row_number() over (partition by id order by url) as rn 
    from urlList
    cross apply STRING_SPLIT( url , '-' )
) t
group by id

我假设,在你的表urlList中,你有一个PK字段id

enter image description here

如果您不使用SQL Server 2016进行分割功能,而使用SQL Server 2017进行字符串聚合功能,则可以在网上搜索split string function个样本。使用FOR XML Path来连接字符串部分,您可以在CTE表达式的帮助下构建解决方案,如下所示

;with cte as (
    select
        urlList.id,
        urlList.url,
        s.id sid,
        s.val
    from urlList
    cross apply dbo.split(url,'-' ) s
)
SELECT
    distinct
    id,
    STUFF(
        (
        SELECT
            '-' + u.val
        FROM cte as u
        where u.id = cte.id
        Order By sid desc
        FOR XML PATH('')
        ), 1, 1, ''
    ) As newurl
FROM cte

请注意,引用的split函数返回一个名为numeric字段的id,它显示了splitted piece的顺序。因此,在连接时,我使用"命令"同一个字段的子句这次按降序排列

答案 2 :(得分:1)

如果有人使用SQL Server 2012或更早版本,则可以通过这种方式实现:

DECLARE @URL VARCHAR(100) = 'https://www.site.sharepoint.com/sites/test/AB-19-CALL'

SELECT TOP 1 dbo.[Reversedata](DATA, '-')
FROM (SELECT * FROM dbo.Splitter(@URL, '/') as t) as tt order by Id desc

在上面的代码中,我使用了两个函数: 1)拆分器:拆分字符串(https://ole.michelsen.dk/blog/split-string-to-table-using-transact-sql.html) 2)反转数据:反转数据(http://picnicerror.net/development/sql-server/reverse-order-words-string-sql-server-2012-01-16/

<强>分配器:

CREATE FUNCTION [dbo].[Splitter]
(
    @String NVARCHAR(4000),
    @Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
    WITH Split(stpos,endpos)
    AS(
        SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
        UNION ALL
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
            FROM Split
            WHERE endpos > 0
    )
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
        'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
    FROM Split
)
GO

<强>反向:

CREATE FUNCTION [dbo].[udf_ReverseSequenceOrder] (
@Input nvarchar(200)
,@Delimiter nvarchar(5)
)

RETURNS nvarchar(200)
AS

BEGIN

DECLARE @Output nvarchar(200)

WHILE LEN(@Input) > 0
BEGIN
IF CHARINDEX(@Delimiter, @Input) > 0
BEGIN
SET @Output = SUBSTRING(@Input,0,CHARINDEX(@Delimiter, @Input)) + @Delimiter + ISNULL(@Output,'')
SET @Input = SUBSTRING(@Input,CHARINDEX(@Delimiter, @Input)+1,LEN(@Input))
END
ELSE
BEGIN
SET @Output = @Input + @Delimiter + ISNULL(@Output,'')
SET @Input = ''
END
END

RETURN SUBSTRING(@Output,0,LEN(@Output))
END

答案 3 :(得分:1)

嗯,这是基于xml的解决方案。对于SQL Server 2008及更高版本。

DECLARE @url VARCHAR(100) = 'AB-19-CALL'

SELECT MyUrl FROM 
(
    SELECT CAST('<Url><Part>' + REPLACE(@url,'-','</Part><Part>') + '</Part></Url>' AS XML) AS my_Xml 
) t1
CROSS APPLY 
(
     SELECT 
        my_Data.D.value('Part[3]','varchar(50)') + '-' + 
        my_Data.D.value('Part[1]','varchar(50)') + '-' + 
        my_Data.D.value('Part[2]','varchar(50)') AS MyUrl
     FROM t1.my_Xml.nodes('/Url') as my_Data(D)
) t2

<强>结果

MyUrl
----------
CALL-AB-19