You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取字符串中第一个连字符后至第三个连字符前的内容?

问题分析与解决方案

先拆解你拿到的SQL原理,再给出满足需求的查询方法。

原SQL查询原理拆解

你提供的查询里,Example1是提取字符串最后一个.后的后缀(比如24XX4),Example2原本要提取倒数第二个-到最后一个-之间的内容(比如LMNO),但代码存在多余的无效操作,具体步骤:

对于Example1(提取24XX4):

  1. REVERSE([Code]):把整个字符串反转,比如EXAMPLE-ABC-1234-XYZZ-DE-LMNO.24XX4反转后变成4XX42.ONML-ED-ZZYX-4321-CBA-ELPMAXE
  2. REPLACE(reverse([Code]), '.', '.'):这一步完全多余,替换相同字符没有任何作用,属于笔误
  3. PARSENAME(..., 1):PARSENAME是SQL Server用于拆分对象名(如数据库.表.列)的函数,默认按.分隔,取从右往左数第1段,这里就是4XX42
  4. REVERSE(...):把4XX42反转回原顺序,得到24XX4

对于Example2(原本要提取LMNO):

代码里的REPLACE(REVERSE([Code]), '-', '-')同样多余,正确写法应该是把-替换成.,让反转后的字符串被.分隔成多段,再用PARSENAME取第2段,反转后得到LMNO。


满足你需求的查询方法

你需要提取第一个-后、第三个-前的内容(比如ABC-1234),这里提供两种可靠实现:

方法一:SUBSTRING+CHARINDEX嵌套(兼容所有SQL Server版本)

通过多次调用CHARINDEX定位三个-的位置,再用SUBSTRING截取目标区间:

SELECT 
    code,
    SUBSTRING(
        Code,
        CHARINDEX('-', Code) + 1,
        CHARINDEX('-', Code, CHARINDEX('-', Code, CHARINDEX('-', Code) + 1) + 1) - (CHARINDEX('-', Code) + 1)
    ) AS TargetContent
FROM [table].[database].[example]
WHERE code IN ('EXAMPLE-ABC-1234-XYZZ-DE-LMNO.24XX4', 'EXAMPLE-CBA-1234-XYZZ-DE-LMNO.24XX4')

如果觉得嵌套复杂,可用CROSS APPLY提前计算-的位置,让代码更清晰:

SELECT 
    code,
    SUBSTRING(Code, pos1 + 1, pos3 - pos1 - 1) AS TargetContent
FROM [table].[database].[example]
CROSS APPLY (
    SELECT 
        CHARINDEX('-', Code) AS pos1,
        CHARINDEX('-', Code, CHARINDEX('-', Code)+1) AS pos2,
        CHARINDEX('-', Code, CHARINDEX('-', Code, CHARINDEX('-', Code)+1)+1) AS pos3
) AS positions
WHERE code IN ('EXAMPLE-ABC-1234-XYZZ-DE-LMNO.24XX4', 'EXAMPLE-CBA-1234-XYZZ-DE-LMNO.24XX4')

方法二:STRING_SPLIT(SQL Server 2016+)

如果你的SQL Server版本支持STRING_SPLIT,可按-拆分字符串后,取第2、3段拼接:

SQL Server 2022及以上(支持ordinal参数,保证顺序):

SELECT 
    code,
    CONCAT(MAX(CASE WHEN ordinal = 2 THEN value END), '-', MAX(CASE WHEN ordinal = 3 THEN value END)) AS TargetContent
FROM [table].[database].[example]
CROSS APPLY STRING_SPLIT(Code, '-', 1)
WHERE code IN ('EXAMPLE-ABC-1234-XYZZ-DE-LMNO.24XX4', 'EXAMPLE-CBA-1234-XYZZ-DE-LMNO.24XX4')
GROUP BY code

SQL Server 2016-2019(无ordinal参数,用ROW_NUMBER生成序号):

SELECT 
    code,
    CONCAT(MAX(CASE WHEN rn = 2 THEN value END), '-', MAX(CASE WHEN rn = 3 THEN value END)) AS TargetContent
FROM [table].[database].[example]
CROSS APPLY (
    SELECT value, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
    FROM STRING_SPLIT(Code, '-')
) AS split
WHERE code IN ('EXAMPLE-ABC-1234-XYZZ-DE-LMNO.24XX4', 'EXAMPLE-CBA-1234-XYZZ-DE-LMNO.24XX4')
GROUP BY code

关于PARSENAME的适用性

PARSENAME最多只能处理4个分隔段,且是从右往左计数,你的字符串按-拆分后段数超过4,且目标内容在左侧,用PARSENAME实现会依赖固定段数,一旦字符串结构变化就会出错,不推荐用它来实现你的需求。

内容的提问来源于stack exchange,提问作者Skyei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:19:53