在特定字符SQL-Standard处拆分字符串

use*_*778 8 string postgresql string-split sql-standards

在我的SQL语句中,我必须从字符'_'处的字符串中提取子字符串.字符串可以是例如'A_XXX''AB_XXX''ABC_XXXX',因此提取的子字符串应该像'A''AB''ABC'.

在Oracle中,使用substr()和instr()函数很容易:

select substr('AB_XXX', 1, instr('AB_XXX', '_')-1) as substring
from dual;
Run Code Online (Sandbox Code Playgroud)

结果将是:

SUBSTRING
------------------------
AB
Run Code Online (Sandbox Code Playgroud)

我需要此查询来检查特定子字符串是否在字符串数组中.

整个查询看起来像:

select 'AB_XXX' from dual
where (instr('ABC_AB_A', substr('AB_XXX', 1, instr('AB_XXX', '_')-1))>0);
Run Code Online (Sandbox Code Playgroud)

有没有办法在SQL-Standard中编写它?

在此先感谢您的帮助.

编辑:

如果PostgreSQL提供了另一种功能,它也会有所帮助.其余的可以用例如IN来解决.真正重要的部分是获得子串.

tot*_*dli 20

tl;博士

使用split_part这是特意为这个内置:

split_part(string, '_', 1)
Run Code Online (Sandbox Code Playgroud)

解释

引用此API 文档

SPLIT_PART() 函数在指定的分隔符上拆分字符串并返回第 n 个子字符串。

3 个参数是要拆分的字符串、分隔符和要返回的部分/子字符串编号(从 1 开始)。

因此,如果您有一个名为的字段string,其中包含诸如此类的内容,AB_XXX并且您希望获得之前的所有内容_,那么您可以将其拆分并获得第一部分/子字符串:split_part(string, '_', 1)

  • 这应该是公认的答案。当前接受的答案(由 a_horse_with_no_name 提供)具有失败且无法概括的边缘情况。 (2认同)

a_h*_*ame 17

你的第二个例子是有点混乱,因为你混合'ABC_AB_A''AB_XXX'不知道这是错字.

但是,如果您只想在第一个之前使用所有字符,_那么以下内容适用于Postgres:

left(col, strpos(col, '_') - 1)
Run Code Online (Sandbox Code Playgroud)

或使用正则表达式:

substring(col from '([A-Z]+)(_{1})')
Run Code Online (Sandbox Code Playgroud)

您也可以在Oracle中使用正则表达式:

regexp_substr(col, '([A-Z]+)(_{1})', 1, 1, 'i', 1)
Run Code Online (Sandbox Code Playgroud)

Postgres的substring函数总是返回正则表达式的第一个捕获组,而在Oracle中,您可以指定所需的组:这是regexp_substr()函数的最后一个参数.

SQLFiddle for Oracle:http:
//sqlfiddle.com/#!4/b138c/SQLFiddle for Postgres:http://sqlfiddle.com/#!15/4b2bb/1

  • 如果分隔符不存在,“left”解决方案将删除字符串的最后一个字符。在这种特殊情况下(或正则表达式解决方案),@totymedli 所示的 split_part 函数是更好的替代方案。 (2认同)