如何从两个不同的patindex中选择子字符串?

时间:2018-05-24 14:25:19

标签: sql sql-server

我有许多不同类型的字符串,但它们都遵循两种相同的模式:

--0971a31c3b8a4c79985d91774720e44b
Content-Disposition: form-data; name="Presentation"; filename=""
Content-Type: text/html
<!DOCTYPE html>
    <html>
        <head>
            <title>Untitled Page</title>
            <meta name="created" content="2013-06-11T06:30:00-08:00" /> 
        </head>
        <body>
            <object data-id="markdown-file" data-attachment="markdown.md" data="name:markdown" type="text/markdown" />
        </body>
    </html>
--0971a31c3b8a4c79985d91774720e44b
Content-Disposition: form-data; name="markdown"; filename="markdown.md"
Content-Type: text/markdown
--0971a31c3b8a4c79985d91774720e44b--

问题1:

我知道如何提取第一部分:ABC123
但是如何提取第二部分? XYZ789

问题2:

我事先无法判断字符串是否遵循-S-模式或-P-模式,每次都可以不同。谁知道我怎么解决这个问题?

谢谢! /索菲

4 个答案:

答案 0 :(得分:1)

这是你需要的吗?

DECLARE @Input VARCHAR(100) = 'ABC123-S-XYZ789'

SELECT
    FirstPart = SUBSTRING(
        @Input,
        1,
        CHARINDEX('-', @Input) - 1),

    SecondPart = SUBSTRING(
        @Input,
        LEN(@Input) - CHARINDEX('-', REVERSE(@Input)) + 2,
        100),

    Pattern = CASE 
        WHEN @Input LIKE '%-S-%' THEN 'S'
        WHEN @Input LIKE '%-P-%' THEN 'P' END

答案 1 :(得分:1)

您可以尝试以下代码:

SELECT CASE WHEN @a LIKE '%-S-%' THEN right(@a, CHARINDEX('-S-', @a)-1)
WHEN @a LIKE '%-P-%' THEN right(@a, CHARINDEX('-P-', @a)-1) 
ELSE NULL END AS 'ColName'
FROM tablename

答案 2 :(得分:0)

如果字符串始终包含此类部分,例如parsename()

,则可以使用ABC123-S-XYZ789
select col, parsename(replace(col, '-', '.'), 1)

但是,parsename()需要 SQL Server + 12 ,否则您可以使用reverse()

select col, reverse(left(reverse(col), charindex('-', reverse(col))-1))

答案 3 :(得分:0)

如果您使用的是SQL Server 2016或更高版本,则可以使用STRING_SPLIT

CREATE TABLE #temp (string VARCHAR(100));

INSERT #temp VALUES ('ABC123-S-XYZ789'),('ABC123-P-XYZ789');

SELECT *, ROW_NUMBER() OVER (PARTITION BY string ORDER BY string) 
    FROM #temp t
    CROSS APPLY STRING_SPLIT(t.string, '-');
  

我事先无法判断字符串是否包含-S-模式或-P-模式

然后,您可以使用CTE获取字符串的特定部分:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY string ORDER BY string) rn
        FROM #temp t
        CROSS APPLY STRING_SPLIT(t.string, '-')
    )
    SELECT * FROM cte WHERE rn = 2