如何在第 n 次出现的定界符之前剪切 varchar/text?数据库
How to cut varchar/text before n'th occurence of delimiter? PostgreSQL
我有字符串(在数据库中保存为 varchar),我必须在第 n 个定界符出现之前剪切它们。
示例输入:
String: 'My-Example-Awesome-String'
Delimiter: '-'
Occurence: 2
输出:
My-Example
我为快速原型实现了这个功能:
CREATE OR REPLACE FUNCTION find_position_delimiter(fulltext varchar, delimiter varchar, occurence integer)
RETURNS varchar AS
$BODY$
DECLARE
result varchar = '';
arr text[] = regexp_split_to_array( fulltext, delimiter);
word text;
counter integer := 0;
BEGIN
FOREACH word IN ARRAY arr LOOP
EXIT WHEN ( counter = occurence );
IF (counter > 0) THEN result := result || delimiter;
END IF;
result := result || word;
counter := counter + 1;
END LOOP;
RETURN result;
END;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE;
SELECT find_position_delimiter('My-Example-Awesome-String', '-', 2);
现在假设字符串不为空(由我将调用函数的查询提供)并且定界符字符串至少包含所提供模式的一个定界符。
但是现在我需要更好的东西来进行性能测试。如果可能的话,我希望看到最通用的解决方案,因为并不是我系统的每个用户都在使用 PostgreSQL 数据库(他们中很少有人喜欢 Oracle、MySQL 或 SQLite),但这不是最重要的.但性能是 - 因为在特定搜索中,该函数甚至可以调用数百次。
我没有找到任何关于快速简便地使用 varchar 作为字符的 table 并检查定界符出现的任何信息(我记得出现的位置,然后创建从第一个字符到第 n 个字符的子字符串定界符位置-1)。有任何想法吗?是更智能的解决方案吗?
@ 编辑:是的,我知道每个数据库中的功能都会有所不同,但功能主体可能非常相似或相同。通用性不是主要目标 :) 对于那个糟糕的函数工作名称感到抱歉,我只是看到它没有正确的含义。
create or replace function trunc(string text, delimiter char, occurence int) returns text as $$
return delimiter.join(string.split(delimiter)[:occurence])
$$ language plpythonu;
# select trunc('My-Example-Awesome-String', '-', 2);
trunc
------------
My-Example
(1 row)
你可以尝试做一些基于此的事情:
select
varcharColumnName,
INSTR(varcharColumnName,'-',1,2),
case when INSTR(varcharColumnName,'-',1,2) <> 0
THEN SUBSTR(varcharColumnName, 1, INSTR(varcharColumnName,'-',1,2) - 1)
else '...'
end
from tableName;
当然,您必须按照自己的方式处理 "else"。它适用于 postgres 和 oracle(已测试),它应该适用于其他 dbms,因为这些是标准 sql 函数
//edit - 作为一个函数,但是这样很难让它跨数据库
CREATE OR REPLACE FUNCTION find_position_delimiter(fulltext varchar, delimiter varchar, occurence integer)
RETURNS varchar as
$BODY$
DECLARE
result varchar := '';
delimiterPos integer := 0;
BEGIN
delimiterPos := INSTR(fulltext,delimiter,1,occurence);
result := SUBSTR(fulltext, 1, delimiterPos - 1);
RETURN result;
END;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE;
SELECT find_position_delimiter('My-Example-Awesome-String', '-', 2);
我有字符串(在数据库中保存为 varchar),我必须在第 n 个定界符出现之前剪切它们。
示例输入:
String: 'My-Example-Awesome-String'
Delimiter: '-'
Occurence: 2
输出:
My-Example
我为快速原型实现了这个功能:
CREATE OR REPLACE FUNCTION find_position_delimiter(fulltext varchar, delimiter varchar, occurence integer)
RETURNS varchar AS
$BODY$
DECLARE
result varchar = '';
arr text[] = regexp_split_to_array( fulltext, delimiter);
word text;
counter integer := 0;
BEGIN
FOREACH word IN ARRAY arr LOOP
EXIT WHEN ( counter = occurence );
IF (counter > 0) THEN result := result || delimiter;
END IF;
result := result || word;
counter := counter + 1;
END LOOP;
RETURN result;
END;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE;
SELECT find_position_delimiter('My-Example-Awesome-String', '-', 2);
现在假设字符串不为空(由我将调用函数的查询提供)并且定界符字符串至少包含所提供模式的一个定界符。
但是现在我需要更好的东西来进行性能测试。如果可能的话,我希望看到最通用的解决方案,因为并不是我系统的每个用户都在使用 PostgreSQL 数据库(他们中很少有人喜欢 Oracle、MySQL 或 SQLite),但这不是最重要的.但性能是 - 因为在特定搜索中,该函数甚至可以调用数百次。
我没有找到任何关于快速简便地使用 varchar 作为字符的 table 并检查定界符出现的任何信息(我记得出现的位置,然后创建从第一个字符到第 n 个字符的子字符串定界符位置-1)。有任何想法吗?是更智能的解决方案吗?
@ 编辑:是的,我知道每个数据库中的功能都会有所不同,但功能主体可能非常相似或相同。通用性不是主要目标 :) 对于那个糟糕的函数工作名称感到抱歉,我只是看到它没有正确的含义。
create or replace function trunc(string text, delimiter char, occurence int) returns text as $$
return delimiter.join(string.split(delimiter)[:occurence])
$$ language plpythonu;
# select trunc('My-Example-Awesome-String', '-', 2);
trunc
------------
My-Example
(1 row)
你可以尝试做一些基于此的事情:
select
varcharColumnName,
INSTR(varcharColumnName,'-',1,2),
case when INSTR(varcharColumnName,'-',1,2) <> 0
THEN SUBSTR(varcharColumnName, 1, INSTR(varcharColumnName,'-',1,2) - 1)
else '...'
end
from tableName;
当然,您必须按照自己的方式处理 "else"。它适用于 postgres 和 oracle(已测试),它应该适用于其他 dbms,因为这些是标准 sql 函数
//edit - 作为一个函数,但是这样很难让它跨数据库
CREATE OR REPLACE FUNCTION find_position_delimiter(fulltext varchar, delimiter varchar, occurence integer)
RETURNS varchar as
$BODY$
DECLARE
result varchar := '';
delimiterPos integer := 0;
BEGIN
delimiterPos := INSTR(fulltext,delimiter,1,occurence);
result := SUBSTR(fulltext, 1, delimiterPos - 1);
RETURN result;
END;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE;
SELECT find_position_delimiter('My-Example-Awesome-String', '-', 2);