【问题标题】:Splitting Multiple of delimiters拆分多个分隔符
【发布时间】:2017-08-23 14:03:04
【问题描述】:

我希望在 MS SQL Server 中拆分这些类型的字符串值。组中的字符数可能会有所不同,但总会有一个句点“。”组之间:

SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' AS StringValue
UNION ALL
SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'
UNION ALL
SELECT '123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC‌​.1234'

所有字符之间总是有 11 个组。我将前 3 组分开,但第 4 至 10 组有问题。

【问题讨论】:

  • 我看到的是 X。你能告诉我们真实的样本数据和你想要的输出吗?此外,您使用的是哪个数据库,因为答案(如果可能)可能是高度特定于数据库的。
  • 欢迎来到 SO;请向create a Minimal, Complete, and Verifiable question提供一些详细信息:示例、预期结果、数据库等;)。
  • 那是一个字符串吗?还要解释一下分裂的逻辑是什么。
  • 我使用的是 MS SQL Server
  • 123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC.1234 分隔符是每个部分之间的句点

标签: sql sql-server delimiter


【解决方案1】:

试试这个

Declare @temp TABLE (id INT IDENTITY,String nvarchar(max))
INSERT INTO @temp
SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' UNION
SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'

 SELECT ROW_NUMBER ()OVER(PARTITION BY id Order by id)AS stringNumber    ,
        Split.a.value('.', 'VARCHAR(1000)') AS stringValue
    FROM (
        SELECT id,CAST('<S>' + REPLACE(String, '.', '</S><S>') + '</S>' AS XML) AS String
        FROM @temp
        ) AS A
    CROSS APPLY String.nodes('/S') AS Split(a)

【讨论】:

    【解决方案2】:

    在 MS SQL Server 中,您可以获得以下内容:

    stringNumber stringValue
    ------------ ----------------
    1            XXX xxxxxxxxxxxx
    2            xxxx
    3            xxx
    4            xxx
    5            xxxx
    6            xxx-xxx
    7            xxxx
    8            xxxxxxx
    9            xxxx
    10           xxxx
    11           xxxx
    1            xxx xxxx
    2            xxxx
    3            xxx
    4            xxxx
    5            xxxx
    6            xxx-xxx_xxxxxxx
    7            xxxx
    8            xxxxxxx
    9            xxxx
    10           xxx
    11           xxxx
    1            123 INTERSTITIAL
    2            1234
    3            123
    4            ABC
    5            1234
    6            123-ABC
    7            1234
    8            ABCDE01
    9            1234
    10           ABC??
    11           1234
    

    通过运行以下命令:

    IF OBJECT_ID(N'dbo.fn_SplitString') IS NOT NULL
        DROP FUNCTION [dbo].[fn_SplitString];
    GO
    
    CREATE FUNCTION [dbo].[fn_SplitString] (
        @string AS VARCHAR(8000)
        ,@stringSeperator AS CHAR(1)
        )
    RETURNS TABLE
    AS
    RETURN
    
    SELECT (number - 1) - LEN(REPLACE(LEFT(@string, number - 1), @stringSeperator, '')) + 1 AS stringNumber
        ,LTRIM(RTRIM(SUBSTRING(@string, number, CHARINDEX(@stringSeperator, @string + @stringSeperator, number) - number))) AS stringValue
    FROM (
        SELECT number
        --SELECT *
        FROM master..spt_values
        WHERE type = 'p'
        ) AS numbers
    WHERE number <= LEN(@string) + 1
        AND SUBSTRING(@stringSeperator + @string, number, 1) = @stringSeperator;
    GO
    
    SELECT stringNumber, stringValue
    FROM (
        SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' AS Input
        UNION ALL
        SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'
        UNION ALL
        SELECT '123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC‌​.1234'
        )OPdata
    CROSS APPLY [dbo].[fn_SplitString](Input,'.');
    GO
    
    IF OBJECT_ID(N'dbo.fn_SplitString') IS NOT NULL
        DROP FUNCTION [dbo].[fn_SplitString];
    

    【讨论】:

      【解决方案3】:

      不使用DECLAREFUNCTION,您可以执行以下操作:

      SELECT Input
          ,ItemNumber = ROW_NUMBER() OVER (PARTITION BY Input ORDER BY N)
          ,Item       = SUBSTRING(Input, N, CHARINDEX('.', Input + '.', N) - N)
      FROM (
          SELECT 'XXX xxxxxxxxxxxx.xxxx.xxx.xxx.xxxx.xxx-xxx.xxxx.xxxxxxx.xxxx.xxxx.xxxx' AS Input
          UNION ALL
          SELECT 'xxx xxxx.xxxx.xxx.xxxx.xxxx.xxx-xxx_xxxxxxx.xxxx.xxxxxxx.xxxx.xxx.xxxx'
          UNION ALL
          SELECT '123 INTERSTITIAL.1234.123.ABC.1234.123-ABC.1234.ABCDE01.1234.ABC‌​.1234'
          ) OPdata
      JOIN (
          SELECT TOP (8000)
              n = ROW_NUMBER()OVER(ORDER BY (SELECT NULL))
          FROM sys.columns a, sys.columns b
          ) n ON SUBSTRING('.' + Input, n, 1) = '.'
      ORDER BY 1,2,3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-07
        • 1970-01-01
        • 2019-05-11
        • 2021-05-22
        • 2017-09-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多