【问题标题】:SQL syntax: Concatenating multiple columns into oneSQL 语法:将多列连接为一列
【发布时间】:2013-08-05 11:27:01
【问题描述】:

我使用的是 PostgreSQL 9.2。我需要从这个标题为房屋的表格中复制地址(分成多列):

 house_id | unit_number| street_number | street| street_extension| suburb | postcode | state | sale_price | sale_date |
----------+------------+-------+-------+-------+-----------------+--------+----------+-------+------------+-----------+
    1     |    2       |  17           | Rose  |     Av          |  Rye   | 3099     | VIC   | 240000     | 2003-12-02|
    2     |            |  3            | Jack  |     St          |  Rye   | 3099     | VIC   | 260000     | 2003-10-02|

在此表中名为 address_list 的单个列中:

house_id  |                 address                  | formatted_address | lat | lon | wkb_geometry | is_processed 
----------+------------------------------------------+-------------------+-----+-----+--------------+--------------
          |                                          |                   |     |     |              |  
          |                                          |                   |     |     |              |  

我的语法是

INSERT INTO address_list (house_id, address)
SELECT house_id, unit_number || '/' || street_number || ' ' || street || ' ' || street_extension || ', ' || suburb || ', ' || state || ' ' || postcode 
FROM houses;

由于源表的 unit_number 字段中有一些空条目,我的语法不起作用。

有没有办法复制 unit_number 加上“\”如果 NOT NULL,而忽略 unit_number 字段和“\”如果 NULL?

我花了几个小时寻找解决方案,但没有运气,因此我将非常感谢任何帮助。

【问题讨论】:

    标签: postgresql syntax concatenation string-formatting


    【解决方案1】:

    使用format 函数

    insert into address_list (house_id, address)
    select
        house_id,
        format(
            '%s%s %s %s, %s, %s %s', 
            unit_number || '\',
            street_number,
            street, street_extension, suburb, state, postcode
        )
    from houses;
    

    %s 标记参数位置。

    http://www.postgresql.org/docs/current/static/functions-string.html#FUNCTIONS-STRING-OTHER

    【讨论】:

      【解决方案2】:

      你可以使用case statement:

      INSERT INTO address_list (house_id, address)
          SELECT house_id, case when unit_number is null then '' else unit_number end || '/' || street_number || ' ' || street || ' ' || street_extension || ', ' || suburb || ', ' || state || ' ' || postcode 
          FROM houses;
      

      【讨论】:

        【解决方案3】:

        由于 unit_number 中有一些空条目而无法工作

        COALESCE()

        如果unit_number唯一可以是NULL的列,使用COALESCE,比CASE简单多了:

        SELECT COALESCE(unit_number || '/', '')
            || street_number    || ' ' 
            || street           || ' ' 
            || street_extension || ', ' 
            || suburb           || ', ' 
            || state            || ' ' 
            || postcode 
        FROM   houses;
        

        如果unit_number 为空,则分隔符/ 也会被删除。 这个原始的解决方案也是最快的

        concat_ws()

        (Postgres 9.1+)
        concat()“带分隔符”

        SELECT concat_ws(' '
               , unit_number || ' /'
               , street_number
               , street 
               , street_extension || ',' 
               , suburb || ',' 
               , state
               , postcode
               )
        FROM   houses;
        

        不过会在/ 之后插入一个空格。所以我在/之前添加了另一个。

        format()

        (Postgres 9.1+)
        对于更复杂的情况,使用format()(Postgres 9.1+),如@Clodoaldo supplied。稍微贵一点。

        【讨论】:

        • 事实上,Agad 提供的 CASE 语法存在问题,但您上面的 concat 语法完美运行。非常感谢。
        • @Mike: agad 的错误是 || '/' 必须在 ELSE 分支内。但在这种情况下,您不会使用 CASE 开头 ...
        猜你喜欢
        • 2019-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-03
        • 1970-01-01
        • 2016-11-18
        • 1970-01-01
        相关资源
        最近更新 更多