11

使用 Postgresql 8.4,当字符串太长时,如何在截断字符串的情况下右填充空格?

问题是当字符串实际上比要填充的字符数长时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 ...

有没有更优雅的解决方案?

4

5 回答 5

14

找到了一个稍微优雅的解决方案:

SELECT greatest(colname,rpad(colname, 2));

例如:

SELECT greatest('foo',rpad('foo', 5));  -- 'foo  ' 
SELECT greatest('foo',rpad('foo', 2));  -- 'foo'  

.


解释它是如何工作的: rpad('foo',5) = 'foo' which is > 'foo' (最适用于字符串和数字) rpad('foo',2) = 'fo' which is < ' foo',所以 'foo' 是由最大函数选择的。

如果你想要左填充的单词,你不能使用 best,因为它比较从左到右(例如 'oo' 和 'foo'),并且在某些情况下,这取决于字符串会更大或更小。我想您可以反转字符串并使用 rpad 并将其反转,或者只使用在这两种情况下都有效的原始解决方案。

于 2014-08-04T12:53:17.783 回答
8

如果您不想一直编写该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)生产什么。如果为 NULL,上述两个版本都rpad_upto将返回 NULL,$1但您可以调整它们以轻松返回其他内容。

于 2012-08-27T19:26:17.027 回答
4

这个怎么样

select case when length(col) < x then rpad(col, x)
else col
end
from table
于 2012-10-10T09:35:56.873 回答
0

假设效率不是您最关心的问题:

select regexp_replace(format('%5s', 'foo'), '(\s*)(\S*)', '\2\1')
  1. format() 将字符串左填充到所需的宽度
  2. 然后 regexp_replace 将任何前导空格移动到末尾。

我想如果你在字符串中有前导空格并且你想保留它们,那将会失败。另请注意, format() 不会在 null 参数上返回 null。

于 2015-05-06T19:37:12.713 回答
0

下面的 PostgreSQL 语句是右填充三个位置值并将列数据类型更改为列“columnname”的文本。我使用 pycharm IDE 来帮助构造语句。该语句将用 000 填充。

我一直在寻找一段时间来解决同样的问题,除了左垫,我想我会分享。

alter table 'schema.tablename' alter column 'columnname' type text using rpad('columnname'::text,3,'0')
于 2020-01-10T19:16:30.177 回答