我有字符串(在数据库中保存为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作为chars表并检查分隔符出现的快速和简单的事情(我可以记住出现的位置,然后从第一个字符到第n个分隔符位置创建子字符串-1)。有任何想法吗?是更智能的解决方案吗?
@ EDIT:是的,我知道每个数据库中的函数都会有所不同,但函数体可能非常类似或相同。一般性不是主要目标:)对于那个糟糕的功能工作名称,我只是看到它没有正确的意义。
答案 0 :(得分: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)
答案 1 :(得分:1)
你可以尝试基于此做点什么:
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;
当然,你必须以你想要的方式处理“其他”。它适用于postgres和oracle(已测试),它应该适用于其他dbms,因为它们是标准的sql函数
//编辑 - 作为一个函数,但是这样很难使它成为跨dbms
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);