11

我想找到一种优雅的方式来模拟 Postgres 中 MySQL 的substring_index()函数的行为。

在 MySQL 中,这很简单:

mysql> create temporary table test1(test varchar(200));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test1 values('apples||oranges'),('apples||grapes');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from test1;
+-----------------+
| test            |
+-----------------+
| apples||oranges |
| apples||grapes  |
+-----------------+
2 rows in set (0.00 sec)

mysql> select substring_index(test, '||', 1) as field1, substring_index(test, '||', -1) as field2 from test1;
+--------+---------+
| field1 | field2  |
+--------+---------+
| apples | oranges |
| apples | grapes  |
+--------+---------+
2 rows in set (0.00 sec)

但是我目前在 PGSQL 中的工作非常难看:

hoth=# create temporary table test1(test text);
CREATE TABLE

hoth=# insert into test1 values('apples||oranges'),('apples||grapes');
INSERT 0 2

hoth=# select * from test1;
      test       
-----------------
 apples||oranges
 apples||grapes
(2 rows)

hoth=# select substring(test, 0, position('||' in test)) as field1,  substring(test, position('||' in test) + 2, char_length(test)) as field2  from test1;
 field1 | field2  
--------+---------
 apples | oranges
 apples | grapes
(2 rows)

也许有一个使用正则表达式的更优雅的解决方案,或者甚至可以通过将字符串拆分为变量中的数组,如果字符串是从子查询或其他东西派生的,这可能会减少开销,我欢迎任何建议。

4

2 回答 2

17

总是花时间浏览手册。

http://www.postgresql.org/docs/current/static/functions-string.html

如果split_part(string text, delimiter text, field int)没有做你想做的(以及更多,如果我理解你的 MySQL 函数),那么你需要解释在哪里以及为什么。

于 2013-10-07T17:18:55.923 回答
6

这是我在 PostgreSQL 中实现(或模拟)MySQL 的 substring_index() 的方法

CREATE OR REPLACE FUNCTION public.substring_index (
  str text,
  delim text,
  count integer = 1,
  out substring_index text
)
RETURNS text AS
$body$
BEGIN
  IF count > 0 THEN
    substring_index = array_to_string((string_to_array(str, delim))[:count], delim);
  ELSE
    DECLARE
      _array TEXT[];
    BEGIN
      _array = string_to_array(str, delim);
      substring_index = array_to_string(_array[array_length(_array, 1) + count + 1:], delim);    
    END;  
  END IF;
END;
$body$
LANGUAGE 'plpgsql'
IMMUTABLE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 5;

这是mysql文档中的示例;

postgres=# SELECT substring_index('www.mysql.com', '.', 2);
 substring_index
-----------------
 www.mysql
(1 row)

postgres=# SELECT substring_index('www.mysql.com', '.', -2);
 substring_index
-----------------
 mysql.com
(1 row)
于 2017-12-15T14:12:51.053 回答