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

PostgreSQL中如何截取第三个下划线之前的子串?

提取字符串到第三个下划线前的子串(SQL解法)

你写的SQL逻辑不对,用REVERSE后找第一个下划线,实际定位的是原字符串最后一个下划线的位置,所以截取的是最后一个下划线之前的开头部分,自然得到22D。下面给你不同数据库的正确解法:

MySQL/MariaDB(最简单)

用SUBSTRING_INDEX函数,直接按分隔符_取前3段:

SELECT SUBSTRING_INDEX('22D_XYZ_xy_100_xyz_123', '_', 3) AS result;

执行后直接返回22D_XYZ_xy,完全符合预期。

PostgreSQL/其他无SUBSTRING_INDEX的数据库

通过多次调用STRPOS定位第三个下划线的位置,再截取子串:

SELECT 
  SUBSTRING(
    '22D_XYZ_xy_100_xyz_123',
    1,
    -- 计算第三个下划线的位置,再减1得到截取终点
    STRPOS(
      SUBSTRING('22D_XYZ_xy_100_xyz_123', STRPOS('22D_XYZ_xy_100_xyz_123', '_') + STRPOS(SUBSTRING('22D_XYZ_xy_100_xyz_123', STRPOS('22D_XYZ_xy_100_xyz_123', '_') + 1), '_') + 1),
      '_'
    ) + STRPOS(SUBSTRING('22D_XYZ_xy_100_xyz_123', STRPOS('22D_XYZ_xy_100_xyz_123', '_') + 1), '_') + STRPOS('22D_XYZ_xy_100_xyz_123', '_') - 1
  ) AS result;

分步逻辑:

  • 第一次STRPOS找第一个下划线的位置
  • 第二次从第一个下划线后开始找第二个下划线的位置,加上第一个下划线的位置得到第二个下划线的总位置
  • 第三次从第二个下划线后开始找第三个下划线的位置,加上前两个的位置得到第三个下划线的总位置
  • 最后截取从开头到第三个下划线位置减1的部分,得到目标子串

通用分步写法(更易读)

用CTE分步计算每个下划线的位置,可读性更强:

WITH str_data AS (
  SELECT '22D_XYZ_xy_100_xyz_123' AS original_str
),
pos1 AS (
  SELECT original_str, STRPOS(original_str, '_') AS p1 FROM str_data
),
pos2 AS (
  SELECT original_str, p1, STRPOS(SUBSTRING(original_str, p1 + 1), '_') + p1 AS p2 FROM pos1
),
pos3 AS (
  SELECT original_str, p2, STRPOS(SUBSTRING(original_str, p2 + 1), '_') + p2 AS p3 FROM pos2
)
SELECT SUBSTRING(original_str, 1, p3 - 1) AS result FROM pos3;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:13:10