从SQL字符串拆分Multipile分隔符

时间:2016-02-03 09:44:27

标签: sql sql-server

如何使用(#和;)分割SQL字符串?

Billing Column,其中字符串以下格式保存

548784545S#15/01/2016;84854555545#13/01/2016;45454554545#21/01/2016

拆分#和;我想要格式

548784545S    15/01/2016
84854555545  13/01/2016
45454554545  21/01/2016

到目前为止我做了什么

SELECT SUBSTRING(CNT_SHIPPING_BILLNO, 1,
            CASE CHARINDEX('#', CNT_SHIPPING_BILLNO)
               WHEN 0
                   THEN LEN(CNT_SHIPPING_BILLNO)
               ELSE CHARINDEX('#', CNT_SHIPPING_BILLNO) - 1
           END)
       AS Billno,
       SUBSTRING(CNT_SHIPPING_BILLNO,
           CASE CHARINDEX('#', CNT_SHIPPING_BILLNO)
               WHEN 0
                   THEN LEN(CNT_SHIPPING_BILLNO) + 1
               ELSE CHARINDEX(';', CNT_SHIPPING_BILLNO) + 1
           END, 1000) AS BillDate
FROM SHIPPINGBILL

这里我只使用上面的查询

获得初始值
548784545S    15/01/2016;84854555545#13/01/2016;45454554545#21/01/2016

5 个答案:

答案 0 :(得分:5)

DECLARE @t VARCHAR(MAX) = '548784545S#15/01/2016;84854555545#13/01/2016;45454554545#21/01/2016'

;WITH cte AS (
    SELECT x = CONVERT(XML,'<p>' + REPLACE(@t, ';', '</p><p>') + '</p>')
)
SELECT PARSENAME(val, 2), PARSENAME(val, 1)
FROM (
    SELECT val = REPLACE(t.c.value('.', 'VARCHAR(MAX)'), '#', '.')
    FROM cte
    CROSS APPLY x.nodes('p') t(c)
) t

输出 -

--------------- ------------
548784545S      15/01/2016
84854555545     13/01/2016
45454554545     21/01/2016

答案 1 :(得分:1)

首先创建一个Table valued函数,以使用;的分隔符拆分字符串。

功能:fn_Split

CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(   
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)  
)
AS
BEGIN

DECLARE @index int
SET @index = -1

WHILE (LEN(@text) > 0)
  BEGIN 
    SET @index = CHARINDEX(@delimiter , @text) 
    IF (@index = 0) AND (LEN(@text) > 0) 
      BEGIN  
        INSERT INTO @Strings VALUES (@text)
          BREAK 
      END 
    IF (@index > 1) 
      BEGIN  
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))  
        SET @text = RIGHT(@text, (LEN(@text) - @index)) 
      END 
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index))
    END
  RETURN
END

然后使用此功能。

<强>查询

DECLARE @str AS VARCHAR(MAX);

SET @str = '548784545S#15/01/2016;84854555545#13/01/2016;45454554545#21/01/2016';

SELECT LEFT(value, CHARINDEX('#', value, 1) - 1) AS Billno,
       RIGHT(value, CHARINDEX('#', REVERSE(value), 1) - 1) AS BillDate
FROM  dbo.fn_Split(@str, ';');

<强>结果

+-------------+------------+
| Billno      | BillDate   |
+-------------+------------+
| 548784545S  | 15/01/2016 |
| 84854555545 | 13/01/2016 |
| 45454554545 | 21/01/2016 |
+-------------+------------+

答案 2 :(得分:0)

另一种方式..

declare @str nvarchar(1000)
SET @str = '548784545S#15/01/2016;84854555545#13/01/2016;45454554545#21/01/2016';

SET @str = replace (@str,';',''' as [date]  union all  select  ''' )
SET @str = replace (@str,'#',''' as [Id],  ''' )
SET @str = 'select ''' +@str +''''


exec (@str)

<强>输出

548784545S  15/01/2016
84854555545 13/01/2016
45454554545 21/01/2016

答案 3 :(得分:0)

如果一条记录总是包含3条记录,则可以声明不同的变量并存储。记录不包含总是3记录 你可以使用这样的脚本;

DECLARE @XPOS INT
DECLARE @XTMPSTR VARCHAR(50)
DECLARE @XBILLSTR VARCHAR(250)
DECLARE @XDATESTR VARCHAR(15)
DECLARE @XNUMVERSTR VARCHAR(15)


SELECT @XBILLSTR='548784545S#15/01/2016;84854555545#13/01/2016;45454554545#21/01/2016'

SELECT @XPOS=INSTR(@XBILLSTR,';')

WHILE @XPOS>0 BEGIN
    SELECT @XTMPSTR=SUBSTRING(@XBILLSTR,1,XPOS-1) -- Contain like548784545S#15/01/2016 
    SELECT @XNUMBERSTR=SUBSTRING(@XTMPSTR,1,CHAINDEX('#',XTMPSTR)
    SELECT @XDATESTR=SUBSTRING(@XTMPSTR,CHARINDEX('#,XTMPSTR),LEN(@XTMPSTR))

    SELECT @XBILLSTR=SUBSTRING(@XBILLSTR,XPOS+1,LEN(@XBILLSTR)
    SELECT @XPOS=INSTR(@XBILLSTR,';')
    -- STORE @XNUMBERSTR AND @XBILLSTR
 END
 -- FOR LAST POSITION 
 SELECT @XTMPSTR=@XBILLSTR
 SELECT @XNUMBERSTR=SUBSTRING(@XTMPSTR,1,CHAINDEX('#',XTMPSTR)
 SELECT @XDATESTR=SUBSTRING(@XTMPSTR,CHARINDEX('#,XTMPSTR),LEN(@XTMPSTR))
 -- STORE @XNUMBER AND STORE @XDATESTR

答案 4 :(得分:0)

您可以使用STRING_SPLIT函数(返回带有片段的单列表,可从SQL Server 2016及更高版本获得):

SELECT
    CASE WHEN CHARINDEX('#',value)>0 
         THEN SUBSTRING(value,1,CHARINDEX('#',value)-1) 
         ELSE value END column1,  
    CASE WHEN CHARINDEX('#',value)>0 
         THEN SUBSTRING(value,CHARINDEX('#',value)+1,len(value))  
         ELSE NULL END as column2
FROM STRING_SPLIT('548784545S#15/01/2016;84854555545#13/01/2016;45454554545#21/01/2016', ';')

结果:

column1      column2
-----------  ----------
548784545S   15/01/2016
84854555545  13/01/2016
45454554545  21/01/2016