在特定字符处拆分字符串 SQL-标准

Split string at specific character SQL-Standard

在我的 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;

结果将是:

SUBSTRING
------------------------
AB

我需要这个查询来检查特定子字符串是否在字符串数组中。

整个查询如下所示:

select 'AB_XXX' from dual
where (instr('ABC_AB_A', substr('AB_XXX', 1, instr('AB_XXX', '_')-1))>0);

有没有办法用SQL-标准写出来?

在此先感谢您的帮助。

编辑:

如果 PostgreSQL 提供了替代功能,它也会有所帮助。其余的可以用例如解决在。 真正重要的部分是获取子字符串。

你的第二个例子有点令人困惑,因为你混合了 'ABC_AB_A''AB_XXX' 不确定这是否是错字。

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

left(col, strpos(col, '_') - 1)

或使用正则表达式:

substring(col from '([A-Z]+)(_{1})')

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

regexp_substr(col, '([A-Z]+)(_{1})', 1, 1, 'i', 1)

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

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

标准 SQL 字符串函数的描述如下: SQL String Functions and Operators.

有一个 substring 函数可以直接提取内容,而无需嵌套函数调用。 Pattern matching 中有详细说明:

The substring function with three parameters, substring(string from pattern for escape-character), provides extraction of a substring that matches an SQL regular expression pattern. As with SIMILAR TO, the specified pattern must match the entire data string, or else the function fails and returns null. To indicate the part of the pattern that should be returned on success, the pattern must contain two occurrences of the escape character followed by a double quote ("). The text matching the portion of the pattern between these markers is returned.

你的情况:

select substring('AB_XX' from '#"%#"#_%' for '#');

结果:

 substring 
-----------
 AB
(1 row)

语法有点奇怪,特别是因为 _ 是单个字符的通配符,所以它必须被引用,但它是 SQL 标准。

对于更多人使用的语法,请考虑 regexp_replace() 或使用 POSIX 正则表达式的类似函数。

tl;博士

使用专门为此构建的 split_part

split_part(string, '_', 1)

说明

引用这个API docs

SPLIT_PART() function splits a string on a specified delimiter and returns the nth substring.

3个参数分别是要拆分的字符串、分隔符、要返回的part/substring个数(从1开始)

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