【问题标题】:select and concatenate everything before and after a certain character选择并连接某个字符之前和之后的所有内容
【发布时间】:2020-03-13 13:49:41
【问题描述】:

我有一个类似AAAA.BBB.CCCC.DDDD.01.A 的字符串,我希望对其进行操作并最终得到AAAA-BBB

我通过编写这段有争议的代码实现了这一点

declare @string varchar(100) = 'AAAA.BBB.CCCC.DDDD.01.A'
select replace(substring(@string,0,charindex('.',@string)) + substring(@string,charindex('.',@string,CHARINDEX('.',@string)),charindex('.',@string,CHARINDEX('.',@string)+1)-charindex('.',@string)),'.','-')

还有其他更优雅、更易读的方法吗?

我正在查看一些 string_split 操作,但无法理解它。

【问题讨论】:

  • 不,不在 SQL Server 中。
  • 我希望在 postgresql 中有类似于 split_part 的东西,但谢谢。
  • 所以你想要第一个之前的所有内容。结合第一后的一切。在第二个之前。用 - 分隔它们?
  • 是的,运行那段代码会输出预期的结果。
  • @madlicksxxx ,另外,各个部分的长度是否始终相同?

标签: sql sql-server string split


【解决方案1】:

如果您愿意接受某些JSON 转换,则可以选择以下方法。您需要将文本转换为有效的 JSON 数组(AAAA.BBB.CCCC.DDDD.01.A 转换为 ["AAAA","BBB","CCCC","DDDD","01","A"])并使用 JSON_VALUE() 从该数组中获取所需的项目:

声明:

DECLARE @string varchar(100) = 'AAAA.BBB.CCCC.DDDD.01.A'
SET @string = CONCAT('["', REPLACE(@string, '.', '","'), '"]')
SELECT CONCAT(JSON_VALUE(@string, '$[0]'), '-', JSON_VALUE(@string, '$[1]'))

结果:

AAAA-BBB

注意:使用这种方法,您可以通过索引(从 0 开始)轻松访问输入字符串中的所有部分。

【讨论】:

    【解决方案2】:

    我觉得这样更干净一点:

    declare @string varchar(100) = 'AAAA.BBB.CCCC.DDDD.01.A'
    select 
      replace( -- replace '.' with '-' (A)
          substring(@string, 1 -- in the substring of @string starting at 1 
              ,charindex('.', @string -- and going through 1 before the index of '.'(B)
                ,charindex('.',@string)+1) -- that is after the first index of the first '.' 
               -1) -- (B)
        ,'.','-') -- (A)
    

    【讨论】:

    • 这是我的选择
    【解决方案3】:

    根据您的字符串中的内容,您可能会滥用 PARSENAME 来执行此操作。旨在分解像adventureworks.dbo.mytable.mycolumn 这样的名称,它的工作原理如下:

    DECLARE @x as VARCHAR(100) = 'aaaa.bbb.cccc.ddddd'
    
    SELECT CONCAT( PARSENAME(@x,4), '-', PARSENAME(@x,3) ) 
    

    您还可以查看混合 STUFF 以删除第一个“。”并用 '-' 替换,然后用下一个 '.' 的索引 LEFT 结果。但它不太可能比这个或凯文的提议更整洁 使用字符串拆分可能会很笨拙:

    SELECT CONCAT(MAX(CASE WHEN rn = 1 THEN v END), '-', MAX(CASE WHEN rn = 2 THEN v END)) 
    FROM (
      SELECT row_number () over (order by (select 0)) rn, value as v 
      FROM string_split(@x,'.')
    ) y WHERE rn IN (1,2)
    

    因为字符串被拆分为行,然后需要对其进行编号,以便过滤和提取您想要的部分。这也依赖于从字符串拆分出来的字符串按照它们在原始字符串中的顺序,MS 不保证会是这种情况

    【讨论】:

    • 这也是我的第一个想法,但如果超过 3 个点就不起作用
    • 使用STRING_SPLIT() 是危险的,因为正如remarks 中提到的那样输出行可能是任何顺序。不保证顺序与输入字符串中子字符串的顺序一致。
    • 也对,我记一下
    猜你喜欢
    • 2011-03-12
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 2016-06-01
    • 2019-02-17
    • 1970-01-01
    相关资源
    最近更新 更多