当完成指示器存在于多个实例中时,提取动态长度的字符串。 Postgres

Extract string of dynamic length when the indicator of completion exists in multiple instances. Postgres

因此,如果我有一个 varchar 长度的字符串列,让我们调用 ID(下面的示例):

97.128.39.256.1460854333288493
25.365.49.12.13454154815132
346.45.156.354.1523425161233

我想像 excel 中的左边一样,抓住 4th 句段左边的所有内容。我如何创建动态字符串来查找句点的第四个实例?

我知道子字符串是一个开始但不确定如何写入存在的动态长度

with t (s) as ( values
    ('97.128.39.256.1460854333288493'),
    ('25.365.49.12.13454154815132'),
    ('346.45.156.354.1523425161233')
)
select a[1] || '.' || a[2] || '.' || a[3] || '.' || a[4]
from (
    select regexp_split_to_array(s, '\.')
    from t
) t (a)
;
    ?column?    
----------------
 97.128.39.256
 25.365.49.12
 346.45.156.354

你也可以试试这个:

mydb=> select regexp_replace('97.128.39.256.1460854333288493', E'^((?:\d+\.){3}\d+).+$', E'\1');
 regexp_replace
----------------
 97.128.39.256
(1 row)

Time: 0.634 ms

这可能是其他人最容易阅读的:

select split_part(i, '.', 1) || '.' || 
       split_part(i, '.', 2) || '.' || 
       split_part(i, '.', 3) || '.' || 
       split_part(i, '.', 4) 
from (select '97.128.39.256.1460854333288493' as i) as sub;

或者如果您不喜欢 split_part 而更喜欢使用数组:

select array_to_string((string_to_array(i, '.'))[1:4], '.') 
from (select '97.128.39.256.1460854333288493' as i) as sub;

我认为数组示例乍一看有点难以掌握,但两者都有效。

根据修改后的问题更新了答案,将 Unix 时间戳也转换为 Greenplum 时间戳:

select 'epoch'::timestamp + '1 second'::interval * 
       (split_part(i, '.', 5)::numeric/1000000) as event_time, 
       array_to_string((string_to_array(i, '.'))[1:4], '.') as ip_address 
from (
       select '97.128.39.256.1460854333288493' as i
     ) as sub;