SQL-分割字符串多个值,多个值

时间:2019-02-26 10:51:57

标签: sql tsql sql-server-2014

我希望将带分隔符的日期字符串拆分为各自的值,并将其放置在结果表的列中。我在以下方面取得了一些成功,对于我的特定应用而言还不够成功 SQL - Split string to columns by multiple delimiters

String (from & to dates)
tblTempDates.tmpString
2019-2-11--2019-2-15,2019-2-20--2019-2-20,2019-2-23--2019-2-23,2019-3-19--2019-3-24

Delimiters
-- seperates from & to
, new record

Output required
tblTempDates2
dtFrom        dtTo
2019-02-11    2019-02-15
2019-02-20    2019-02-20
2019-02-23    2019-02-23
2019-02-19    2019-03-24

在此先感谢:-)

3 个答案:

答案 0 :(得分:1)

可以使用while语句来拆分csv,

    declare @a table(datefromto varchar(500))

    declare @b table(fromdate varchar(500),todate varchar(500))

    insert into @a values ('2019-2-11--2019-2-15,2019-2-20--2019-2-20,2019-2-23--2019-2-23,2019-3-19--2019-3-24');

    declare @datefromto varchar(500) = (select max(datefromto) from @a)

    declare @datesplit int
    set @datesplit= (SELECT charindex(',',@datefromto))



    WHILE (SELECT charindex(',',@datefromto) FROM @a) <> 0
    BEGIN  



       insert into @b select Left(left(@datefromto,@datesplit),charindex('--',@datefromto)-1) ,
       Right(left(@datefromto,@datesplit-1),charindex('--',@datefromto)-1) from @a


       set @datesplit= (SELECT charindex(',',@datefromto))
       set @datefromto= right(@datefromto,len(@datefromto)-@datesplit)

    END  
       insert into @b select Left(left(@datefromto,@datesplit),charindex('--',@datefromto)-1) ,
       Right(left(@datefromto,@datesplit-1),charindex('--',@datefromto)-1) from @a

    select * from @b

答案 1 :(得分:0)

如果您的SQL Server版本支持的话,这是使用STRING_SPLIT执行此操作的一种好方法:

SELECT
    LEFT(value, CHARINDEX('--', value) - 1) AS dtFrom,
    SUBSTRING(value, CHARINDEX('--', value) + 2, 20) AS dtTo
FROM
(
    SELECT STRING_SPLIT(input, ',')
    FROM yourTable
) t;

此方法首先使用STRING_SPLIT通过逗号将每个子日期/日期子字符串拆分为单独的行。然后,它使用基本字符串函数来隔离开始日期和结束日期。

答案 2 :(得分:0)

对于STRING_SPLIT()(或OPENJSON之前的版本,我建议采用这种方法:

DECLARE @tbl TABLE(ID INT IDENTITY, YourString VARCHAR(1000));
INSERT INTO @tbl VALUES('2019-2-11--2019-2-15,2019-2-20--2019-2-20,2019-2-23--2019-2-23,2019-3-19--2019-3-24');

WITH Casted AS
(
    SELECT *
         , CAST('<x><y>' + REPLACE(REPLACE(YourString,'--','</y><y>'),',','</y></x><x><y>') + '</y></x>' AS XML) AsXml
    FROM @tbl 
)
SELECT  ID 
       ,x.value('y[1]','date') AS Date1
       ,x.value('y[2]','date') AS Date2
FROM Casted
CROSS APPLY AsXml.nodes('/x') A(x);

简而言之:

某些字符串替换将您的 multi-level-CSV 转换为这样的XML

<x>
  <y>2019-2-11</y>
  <y>2019-2-15</y>
</x>
<x>
  <y>2019-2-20</y>
  <y>2019-2-20</y>
</x>
<x>
  <y>2019-2-23</y>
  <y>2019-2-23</y>
</x>
<x>
  <y>2019-3-19</y>
  <y>2019-3-24</y>
</x>

然后,我们可以使用.nodes()将所有重复的<x>作为派生表。然后,我们使用.value()按照其位置获取<y>