【问题标题】:Is there a way to split part a column to extract the text after a '-' in SQL Server?有没有办法在 SQL Server 中拆分列以提取“-”之后的文本?
【发布时间】:2020-06-23 08:44:01
【问题描述】:

我知道人们以前以其他方式提出过这个问题,但我对通过变量推送单个字符串不感兴趣。

我有一列包含如下数据:QWERTYUIOP-1、QWERTYUIOP-XL、ASDFG-2、HGJFK-SM。 该列称为产品。我需要能够在“-”之后提取文本,以便将其作为大小存储在另一列中。对于这个例子,让我们调用表 products。

如何在 SQL Server 中做到这一点?在 postgreSQL 中使用 split_part 非常简单,但除了 string_split 之外似乎没有类似的函数,并且仅适用于表。当我尝试对列使用它时,它说 string_split 不存在。

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: sql-server string text-extraction


    【解决方案1】:

    一种方法是使用STUFF 删除前导字符,并使用CHARINDEX 查找这些前导字符的结束位置:

    SELECT V.YourString,
           STUFF(V.YourString,1,CHARINDEX('-',V.YourString),'') AS TrailingCharacters
    FROM (VALUES('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM'))V(YourString)
    

    好的,现在球门柱已经移动了。您可以修改上述内容以使用 REVERSE 来获取最后一个 - 字符的位置:

    SELECT V.YourString,
           STUFF(V.YourString,1,LEN(V.YourString) - CHARINDEX('-',REVERSE(V.YourString))+1,'') AS TrailingCharacters
    FROM (VALUES('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM'),('QWER-WETT-EWT-1'))V(YourString)
    

    或者,您可以使用DelimitedSplit8k_LEAD 之类的字符串拆分器并获取“最后”行:

    WITH CTE AS(
        SELECT V.YourString,
               DS.ItemNumber,
               DS.Item,
               ROW_NUMBER() OVER (PARTITION BY V.YourString ORDER BY DS.ItemNumber DESC) AS RN
        FROM (VALUES('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM'),('QWER-WETT-EWT-1'))V(YourString)
             CROSS APPLY dbo.DelimitedSplit8K(V.YourString,'-') DS)
    SELECT YourString,
           DS.Item
    FROM CTE
    WHERE RN = 1;
    

    【讨论】:

    • 您好,谢谢,如果产品是这样的 QWER-WETT-EWT-1,我只想检索结尾文本怎么办?
    • 这就是为什么提供代表性样本数据很重要,@JK1993。像这样的例子应该在你的问题中,这样用户就不会“浪费”时间给出不会回答 Real 问题的答案。
    • 对不起,如果您觉得自己浪费了时间,感谢您的帮助!
    【解决方案2】:

    您可以使用 String_split 和 JSON_VALUE 的组合将值拆分为多个列。

    DECLARE @productSize table(ProductName VARCHAR(500))
    INSERT INTO @productSize values
    ('QWERTYUIOP-1,QWERTYUIOP-XL, ASDFG-2, HGJFK-SM')
    
    SELECT 
    JSON_VALUE(concat('["',replace(value,'-','","'),'"]'),'$[0]') as productname,
    JSON_VALUE(concat('["',replace(value,'-','","'),'"]'),'$[1]') as productSize
    from @productSize
    cross apply STRING_SPLIT(ProductName,',') 
    
    +-------------+-------------+
    | productname | productSize |
    +-------------+-------------+
    | QWERTYUIOP  | 1           |
    | QWERTYUIOP  | XL          |
    |  ASDFG      | 2           |
    |  HGJFK      | SM          |
    +-------------+-------------+
    

    【讨论】:

      【解决方案3】:
      select 
       left(product,charindex('-',product)-1) product_code
       ,right(product,len(product)-charindex('-',product)) product_size
      from (values('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM')) p (product)
      

      不要将STRING_SPLIT 用于您的目的,因为字符串会被分割成行并且

      输出行可以是任意顺序。不保证顺序与输入字符串中子字符串的顺序一致。

      https://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver15

      所以你永远不会知道哪个是左(代码)哪个是右(大小)。

      【讨论】:

        猜你喜欢
        • 2020-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-25
        • 1970-01-01
        • 1970-01-01
        • 2020-04-27
        • 2010-11-04
        相关资源
        最近更新 更多