在2012版中用连字符在SQL中拆分字符串

时间:2018-12-13 12:41:26

标签: sql-server tsql split

我在一个列中有多个字符串,在列中我得到了最后一个字符串 下面是三个类似的示例,我在字符串中可能有不同的数字连字符,但所需的结果是我在最后一个连字符之前有字符串

1. abc-def-Opto
2. abc-def-ijk-5C-hello-Opto
3. abc-def-ijk-4C-hi-Build 
4. abc-def-ijk-4C-123-suppymanagement

所需结果集为

  1. def
  2. 你好
  3. 123

如何在SQL查询中执行此操作以获取此结果集。我有MSSQL 2012版本 需要可以获取结果集的通用sql

4 个答案:

答案 0 :(得分:1)

有很多分割/解析字符串的方法。 ParseName()可能会失败,因为您可能有4个以上的职位。

一个选择(只是为了好玩)是使用一些XML。

  1. 我们反转字符串
  2. 转换为XML
  3. 获取第二个节点
  4. 颠倒最终演示文稿的期望值

示例

Declare @YourTable Table ([SomeCol] varchar(50))
Insert Into @YourTable Values 
 ('abc-def-Opto')
,('abc-def-ijk-5C-hello-Opto')
,('abc-def-ijk-4C-hi-Build')
,('abc-def-ijk-4C-123-suppymanagement')

Select * 
      ,Value = reverse(convert(xml,'<x>'+replace(reverse(SomeCol),'-','</x><x>')+'</x>').value('x[2]','varchar(150)'))
 from @YourTable

返回

SomeCol                             Value
abc-def-Opto                        def
abc-def-ijk-5C-hello-Opto           hello
abc-def-ijk-4C-hi-Build             hi
abc-def-ijk-4C-123-suppymanagement  123

答案 1 :(得分:1)

无需使用XML内容,只需使用sql server的字符串函数即可。

Declare @YourTable Table ([SomeCol] varchar(50))
Insert Into @YourTable Values 
 ('abc-def-Opto')
,('abc-def-ijk-5C-hello-Opto')
,('abc-def-ijk-4C-hi-Build')
,('abc-def-ijk-4C-123-suppymanagement');


SELECT * 
        ,RTRIM(LTRIM(REVERSE( 
            SUBSTRING(
                    SUBSTRING(REVERSE([SomeCol]) , CHARINDEX('-', REVERSE([SomeCol]))  +1 , LEN([SomeCol]) )
                     , 1 , CHARINDEX('-', SUBSTRING(REVERSE([SomeCol]) , CHARINDEX('-', REVERSE([SomeCol]))  +1 , LEN([SomeCol]) ) ) -1
                    )
                )))
FROM @YourTable

答案 2 :(得分:0)

我不确定该脚本是否会完全满足您的要求,但我只是想提供一个如何拆分数据的想法

IF OBJECT_ID('tempdb..#Temp')IS NOT NULL
DROP TABLE #Temp
;WITH CTE(Id,data)
AS
(
SELECT 1,'abc-def-Opto'                 UNION ALL
SELECT 2,'abc-def-ijk-5C-hello-Opto'    UNION ALL
SELECT 3,'abc-def-ijk-4C-hi-Build'      UNION ALL
SELECT 4,'abc-def-ijk-4C-123-suppymanagement'
)
,Cte2
AS
(
SELECT Id, CASE WHEN Id=1   AND  Setdata=1 THEN data
                WHEN Id=2   AND  Setdata=2 THEN data
                WHEN Id=3   AND  Setdata=3 THEN data
                WHEN Id=4   AND  Setdata=4 THEN data
                ELSE NULL 
            END AS Data
FROM
(
SELECT  Id,
        Split.a.value('.','nvarchar(1000)') AS Data,
        ROW_NUMBER()OVER(PARTITION BY id ORDER BY id) AS Setdata
FROM(
SELECT Id,
       CAST('<S>'+REPLACE(data ,'-','</S><S>')+'</S>' AS XML) AS data
FROM CTE
) AS A
CROSS APPLY data.nodes('S') AS Split(a)
)dt
)
SELECT * INTO #Temp FROM Cte2 

SELECT STUFF((SELECT DISTINCT ', '+ 'Set_'+CAST(Id  AS VARCHAR(10))+':'+Data
FROM #Temp WHERE ISNULL(Data,'')<>'' FOR XML PATH ('')),1,1,'')

结果

Set_1:abc, Set_2:def, Set_3:ijk, Set_4:4C

答案 3 :(得分:0)

你可以喜欢

$number = 12.34
Write-host "The final number is $([int]$number)"
# OUTPUT:
# The final number is 12

返回:

WITH CTE AS
(
  SELECT 1 ID,'abc-def-Opto' Str
  UNION
  SELECT 2, 'abc-def-ijk-5C-hello-Opto'
  UNION
  SELECT 3, 'abc-def-ijk-4C-hi-Build'
  UNION
  SELECT 4, 'abc-def-ijk-4C-123-suppymanagement'
)
SELECT ID,
       REVERSE(LEFT(REPLACE(P2, P1, ''), CHARINDEX('-', REPLACE(P2, P1, ''))-1)) Result
FROM (
       SELECT LEFT(REVERSE(Str), CHARINDEX('-', REVERSE(Str))) P1,
              REVERSE(Str) P2,
              ID
       FROM CTE
     ) T;

Demo