使用Postgresql 8.4,当字符串太长时,如何用空格without截断字符串?
问题是rpad
截断字符串实际上长于要填充的字符数。示例:
SELECT rpad('foo', 5); ==> 'foo ' -- fine
SELECT rpad('foo', 2); ==> 'fo' -- not good, I want 'foo' instead.
我发现的最短的解决方案根本不涉及rpad
:
SELECT 'foo' || repeat(' ', 5-length('foo')); ==> 'foo ' -- fine
SELECT 'foo' || repeat(' ', 2-length('foo')); ==> 'foo' -- fine, too
但是这看起来很难看,恕我直言。请注意,我当然没有选择字符串'foo',而是从列中选择:
SELECT colname || repeat(' ', 30-length(colname)) FROM mytable WHERE ...
还有更优雅的解决方案吗?
找到了一个稍微优雅的解决方案:
SELECT greatest(colname,rpad(colname, 2));
例如:
SELECT greatest('foo',rpad('foo', 5)); -- 'foo '
SELECT greatest('foo',rpad('foo', 2)); -- 'foo'
。
要说明其工作原理:rpad('foo',5)='foo',即>'foo'(最适用于字符串和数字)rpad('foo',2)='fo'这是
如果您想要用左键填充的单词,则不能使用最大的值,因为它会左右比较(例如'oo'与'foo'),在某些情况下,根据字符串的不同,该值可能会更大或更小。我想您可以反转字符串并使用rpad并将其反转回来,或者只使用在两种情况下均适用的原始解决方案。
[如果您不想一直写repeat
业务,只需为其编写自己的函数。像这样的东西:
create or replace function rpad_upto(text, int) returns text as $$
begin
if length($1) >= $2 then
return $1;
end if;
return rpad($1, $2);
end;
$$ language plpgsql;
或此:
create or replace function rpad_upto(text, int) returns text as $$
select $1 || repeat(' ', $2 - length($1));
$$ language sql;
然后您可以说类似的内容:
select rpad_upto(colname, 30) from mytable ...
您可能想考虑当您在rpad_upto(null, n)
上要生产什么。如果rpad_upto
为NULL,则以上两个版本的$1
都将返回NULL,但是您可以对其进行调整以轻松返回其他内容。
怎么样
select case when length(col) < x then rpad(col, x)
else col
end
from table
假设效率不是您最关心的问题:
select regexp_replace(format('%5s', 'foo'), '(\s*)(\S*)', '\2\1')
我想如果字符串中有前导空格并且想要保留它们,那将失败。另请注意,format()不会在null参数上返回null。
下面的PostgreSQL语句在右边填充三个位置值,并将列数据类型更改为列'columnname'的文本。我使用pycharm IDE帮助构建语句。该语句将填充000。
我一直在寻找解决同一问题的时间,除了左脚垫,我想我会分享。
alter table 'schema.tablename' alter column 'columnname' type text using rpad('columnname'::text,3,'0')