SQL-只保留方括号和数据

时间:2017-03-02 05:15:59

标签: sql sql-server

我一直在寻找一种动态解析字符串的方法:

输入: A[1]/B2[2]/C_D[1]

输出: [1][2][1]

5 个答案:

答案 0 :(得分:2)

如果兼容级别为130或更高,则可以尝试STRING_SPLIT。 (根据文档,不是Azure的默认设置。您可能必须在数据库范围内更改设置。)

如果您将字符串拆分为' [',那么您将拥有两组值:包含']'那些不是。如果你的字符串包含平衡的左右括号,则第一个单词应该没有']',因为它包含第一个开头之前的所有内容' ['。其他所有单词都应包含结尾']'。

您可以删除第一个字,然后在']'上再次应用STRING_SPLIT。此时,let-call-them-even行将成为索引,而call-they-odd行将是']'之后的文本。在下一个' ['。

之前

像这样:

s = 'firstword[1][2] another word [foobar] biscuit'

SELECT VALUE FROM STRING_SPLIT(s, '[')

应该得到你:

1: 'firstword'  #<-- No brackets here
2: '1]'
3: '2] another word '
4: 'foobar] biscuit'

当然,你可以放弃第一行。再次应用SPLIT_STRING可以获得:

'1', ''
'2', ' another word'
'foobar', ' biscuit'

保留左栏,丢弃右栏,鲍勃是你的叔叔!

答案 1 :(得分:2)

在CTE中使用SUBSTRING和CHARINDEX内置函数:

 DECLARE @String VARCHAR(200) = 'A[1]/B2[2]/C_D[1]'
 ;WITH CTE_Split( SplitStr , String ) AS
 (
    SELECT SUBSTRING(@String      
    ,CHARINDEX('[',@String),CHARINDEX('[',@String)+1),SUBSTRING(@String 
    ,CHARINDEX('/',@String)+1,LEN(@String))
    UNION ALL
    SELECT CASE WHEN CHARINDEX('[',String) = 0 THEN '' ELSE SUBSTRING(String  
    ,CHARINDEX('[',String),CHARINDEX('[',String)) END,
    CASE WHEN CHARINDEX('/',String) = 0 THEN '' ELSE SUBSTRING(String  
    ,CHARINDEX('/',String)+1,LEN(String)) END
    FROM CTE_Split
    WHERE String <> ''
  )

  SELECT SplitStr FROM CTE_Split 

  [OR]

  This query for all scenarios :

   DECLARE @String VARCHAR(200) = 'A[1]/B2[2]/C_D[1]/C_D[288]/'

   ;WITH CTE_Split( SplitStr , String ) AS
   (
      SELECT SUBSTRING(@String,0,CHARINDEX('/',@String)),SUBSTRING(@String  
      ,CHARINDEX('/',@String)+1,LEN(@String))
      UNION ALL
      SELECT CASE WHEN CHARINDEX('/',String) = 0 THEN '' ELSE   
      SUBSTRING(String ,0,CHARINDEX('/',String)) END,
      CASE WHEN CHARINDEX('/',String) = 0 THEN '' ELSE SUBSTRING(String  
      ,CHARINDEX('/',String)+1,LEN(String)) END
      FROM CTE_Split
      WHERE String <> ''
  )

  SELECT SUBSTRING(SplitStr,CHARINDEX('[',SplitStr),CHARINDEX(']',SplitStr))
  FROM CTE_Split 

答案 2 :(得分:2)

只需使用while循环。

declare @str varchar(max), @newStr varchar(max), @orgStr varchar(max)
set @orgStr = 'A[1]/B2[2]/C_D[1]'
set @newStr = ''
set @Str = @orgStr
while (1=1)
begin
    if (CHARINDEX('[',@str) <> 0)
        begin
            set @newStr = @newStr + SUBSTRING(@str,CHARINDEX('[',@str), CHARINDEX(']',@str) - CHARINDEX('[',@str)+1)
            set @str = STUFF(@str, CHARINDEX('[',@str), CHARINDEX(']',@str) - CHARINDEX('[',@str)+1, '')
        end
    else
        break
end
select @orgStr as input, @newStr as result

答案 3 :(得分:1)

&#13;
&#13;
--===== Create and populate the Tally table on the fly
 SELECT TOP 11000 --equates to more than 30 years of dates
        IDENTITY(INT,1,1) AS N
   INTO dbo.Tally
   FROM Master.dbo.SysColumns sc1,
        Master.dbo.SysColumns sc2

--===== Add a Primary Key to maximize performance
  ALTER TABLE dbo.Tally
    ADD CONSTRAINT PK_Tally_N 
        PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100

--===== Allow the general public to use it
  GRANT SELECT ON dbo.Tally TO PUBLIC


  --===== Simulate a passed parameter
DECLARE @Parameter VARCHAR(8000) 
    SET @Parameter = 'A[1]/B2[2]/C_D[1]' 

--===== Suppress the auto-display of rowcounts to keep them from being
    -- mistaken as part of the result set.
   SET NOCOUNT ON

--===== Get the items in the brackets and number them 
 SELECT  '[' + SUBSTRING(@Parameter,N+1,CHARINDEX(']',@Parameter,N+1)-N-1) + ']'
   FROM dbo.Tally
  WHERE N < LEN(@Parameter)
    AND SUBSTRING(@Parameter,N,1) = '[' 
&#13;
&#13;
&#13;

请尝试像这样的逻辑

答案 4 :(得分:1)

可以通过子循环和charindex的组合使用while循环。

<强>查询

declare @str as varchar(max) = 'A[1]/B2[2]/C_D[1]';
declare @len as int = len(@str);
declare @i as int = 0;
declare @str2 as varchar(max) = @str;
declare @res as varchar(max) = '';

while(@len >= @i)
begin
    if (charindex('[',@str2) <> 0)
    begin
        set @res += substring(@str2, 
                              charindex('[', @str2, 1), 
                              charindex(']', @str2, 1) - charindex('[', @str2, 1) + 1)
        set @i += charindex(']', @str2, 1);
        set @str2 = right(@str2, @len - @i)
    end
    else
      break;    
end
select @res;