在SQL 服务器中,有没有办法拆分列的一部分以提取“-”之后的文本?

Is there a way to split part a column to extract the text after a '-' in SQL Server?

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

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

如何在 SQL 服务器中执行此操作?在带有 split_part 的 postgreSQL 中它非常简单,但是除了 string_split 之外似乎没有类似的功能,并且只适用于 tables。当我尝试对列使用它时,它说 string_split 不存在。

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

一种方法是使用 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;

您可以结合使用 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          |
+-------------+-------------+
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 用于您的目的,因为字符串被拆分成行并且

The output rows might be in any order. The order is not guaranteed to match the order of the substrings in the input string.

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

所以你永远不知道哪个是左(代码)哪个是右(尺寸)。