如何使用Postgres轻松地从文本字段中获取首字母

时间:2015-10-23 21:41:59

标签: sql postgresql

我使用的是Postgres版本9.4,表格中有一个full_name字段。

在某些情况下,我想在我的表格中输入姓名首字母而不是姓名的全名。

类似的东西:

Name        | Initials
------------------------
Joe Blow    | J. B.  
Phil Smith  | P. S.  

full_name字段是一个字符串值(显然),我认为最好的解决方法是将字符串拆分为一个foreach空格数组,即:。

select full_name, string_to_array(full_name,' ') initials
from my_table

这会产生以下结果集:

Eric A. Korver;{Eric,A.,Korver}
Ignacio Bueno;{Ignacio,Bueno}
Igmar Mendoza;{Igmar,Mendoza}

现在,我唯一缺少的是如何遍历每个数组元素并将第一个字符拉出来。我最终会使用substring()来获取每个元素的初始字符 - 但是我只是坚持如何在运行中循环它们。

有人有一个简单的方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:4)

let combos = [|"win8FF40";"win10Chrome45";"win7IE11"|] unnest

一起使用
string_agg

答案 1 :(得分:1)

<强> SqlFiddleDemo

WITH add_id as (
     SELECT n.*, row_number() over (order by "Name") as id
     FROM names n
),
split_names as (
     SELECT
          id,
          regexp_split_to_table("Name", E'\\s+') as single_name
     FROM add_id
),
initials as (
      SELECT id, left(single_name, 1) || '.' as initial
      FROM split_names
),
final as (
      SELECT id, string_agg(initial, ' ')
      FROM initials
      GROUP BY id
) 
SELECT a.*, f.*
FROM add_id a
JOIN final f using(id)

对于调试,我创建Initial以显示与string_agg

的匹配程度
|           Name | Initials | id | id | string_agg |
|----------------|----------|----|----|------------|
| Eric A. Korver | E. A. K. |  1 |  1 |   E. A. K. |
|  Igmar Mendoza |    I. M. |  2 |  2 |      I. M. |
|  Ignacio Bueno |    I. B. |  3 |  3 |      I. B. |
|       Joe Blow |    J. B. |  4 |  4 |      J. B. |
|     Phil Smith |    P. S. |  5 |  5 |      P. S. |

经过一些工作,我得到了一个紧凑版SqlFiddleDemo

  SELECT "Name", string_agg(left(single_name, 1) || '.', '') as Initials
  FROM (
        SELECT
          "Name",
          regexp_split_to_table("Name", E'\\s+') as single_name
        FROM names
       ) split_names
  GROUP BY "Name"

<强>输出

|           Name | initials |
|----------------|----------|
| Eric A. Korver |   E.K.A. |
|  Igmar Mendoza |     M.I. |
|  Ignacio Bueno |     I.B. |
|       Joe Blow |     B.J. |
|     Phil Smith |     P.S. |

答案 2 :(得分:1)

如果要在多个查询中使用类似的逻辑,也可以为此创建辅助函数。看看这个

--
-- Function to extract a person's initials from the full name.
--

DROP FUNCTION IF EXISTS get_name_initials(TEXT);

CREATE OR REPLACE FUNCTION get_name_initials(full_name TEXT)
RETURNS TEXT AS $$
DECLARE 
    result TEXT :='';
    part VARCHAR :='';
BEGIN
    FOREACH part IN ARRAY string_to_array($1, ' ') LOOP
        result :=  result || substr(part, 1, 1) || '.';
    END LOOP;

    RETURN result;
END;
$$ LANGUAGE plpgsql;

现在您只需使用此function即可获得此类缩写。

SELECT full_name, get_name_initials(full_name) as initials
FROM my_table;

SELECT get_name_initials('Phil Smith'); -- Returns P. H. 
SELECT get_name_initials('Joe Blow'); -- Returns J. B.