如何在SQL Server 2008中子字符串值

时间:2012-11-21 09:41:44

标签: sql-server-2008

我有以下字符串

KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52
IYT_2012_CBBI1_S_66_2012-09-21_15_28_53

我希望在第一个_之后提取所有内容。在第5 _

之前

例如:

2012_CBBE2_E_12704 
2012_CBBI1_S_66

3 个答案:

答案 0 :(得分:8)

方法1.嵌套的CHARINDEX调用。

使用CHARINDEX('_', stringvalue)获取 _ 中第一个stringvalue的位置。如果您将该位置作为第三个参数传递,您可以指示CHARINDEX从某个位置开始搜索:

CHARINDEX(`_`, stringvalue, startpos)

现在,如果起始位置是CHARINDEX('_', stringvalue)+1的结果,即如下:

CHARINDEX(`_`, stringvalue, CHARINDEX(`_`, stringvalue) + 1)
然后,这将给你第二个_的位置。因此,要找到第五个_,您需要再嵌套CHARINDEX三次:

WITH aTable AS (
  SELECT
    *
  FROM
    (VALUES
      ('KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52'),
      ('IYT_2012_CBBI1_S_66_2012-09-21_15_28_53')
    ) AS v (aStringColumn)
),
positions AS (
  SELECT
    aStringColumn,
    Underscore1 = CHARINDEX('_', aStringColumn),
    Underscore5 = CHARINDEX('_',
                            aStringColumn,
                            CHARINDEX('_',
                                      aStringColumn,
                                      CHARINDEX('_',
                                                aStringColumn,
                                                CHARINDEX('_',
                                                          aStringColumn,
                                                          CHARINDEX('_',
                                                                    aStringColumn
                                                                   ) + 1
                                                         ) + 1
                                               ) + 1
                                     ) + 1
                           )
  FROM
    aTable
)
SELECT
  aSubstring = SUBSTRING(aStringColumn,
                         Underscore1 + 1,
                         Underscore5 - Underscore1 - 1
                        )
FROM
  positions
;

方法2.字符拆分+排名。

  1. 使用numbers table将每个字符串拆分为单个字符,沿途拉动其位置。

  2. 对字符串中每个字符的出现进行排名。

  3. 获取两个子集:

    1),字符为_,排名为1;

    2),字符为_,排名为5。

    互相加入这些子集。

  4. 与方法1类似,使用_#1和_#5的相应位置来获取子字符串。

  5. WITH aTable AS (
      SELECT
        *
      FROM
        (VALUES
          ('KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52'),
          ('IYT_2012_CBBI1_S_66_2012-09-21_15_28_53')
        ) AS v (aStringColumn)
    ),
    split AS (
      SELECT
        t.aStringColumn,
        aChar    = SUBSTRING(t.aStringColumn, n.Number, 1),
        Position = n.Number
      FROM
        aTable t
        INNER JOIN Numbers n
          ON n.Number BETWEEN 1 AND LEN(t.aStringColumn)
    ),
    ranked AS (
      SELECT
        *,
        rnk = ROW_NUMBER() OVER (PARTITION BY aStringColumn, aChar ORDER BY Position)
      FROM
        split
      WHERE
        aChar = '_'
    )
    SELECT
      aSubstring = SUBSTRING(first.aStringColumn,
                             first.Position + 1,
                             fifth.Position - first.Position - 1
                            )
    FROM
      ranked first
      INNER JOIN ranked fifth
        ON first.aStringColumn = fifth.aStringColumn
    WHERE
      first.rnk = 1
      AND fifth.rnk = 5
    ;
    

    注意:两种方法都假定每个aStringColumn值至少有5个下划线字符。

答案 1 :(得分:5)

您可以使用SUBSTRING函数从给定字符串中提取子字符串。

SELECT SUBSTRING('KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52', 6, 18);

答案 2 :(得分:1)

它狡猾地命名为SubString

,如

Select Substring('KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52',6,18)

如果你想在字符串中找到它,那么CharIndex会很有用。 你确定你想在SQL中这样做,它会变得混乱和缓慢,你需要创建一个UDF,或者使用CLR来实现它。