合并两列并添加到一个新列中

时间:2012-09-07 02:36:02

标签: sql postgresql null concatenation

在PostgreSQL中,我想使用SQL语句组合两列并从中创建一个新列。

我正在考虑使用concat(...),但是有更好的方法吗? 最好的方法是什么?

3 个答案:

答案 0 :(得分:66)

一般来说,我同意@kgrittn's advice。去吧。

但要解决有关concat()的基本问题:如果您需要处理空值,则新函数concat()非常有用 - 并且null中既没有排除你的问题也不是你提到的问题。

如果可以排除空值,那么旧的(SQL标准)连接运算符||仍然是最佳选择,@luis' answer就可以了:

SELECT col_a || col_b;

如果您的任何一列都可以为null,那么在这种情况下结果将为null。您可以使用COALESCE进行辩护:

SELECT COALESCE(col_a, '') || COALESCE(col_b, '');

但随着更多的争论,这会很快变得乏味。这就是concat()进来的地方,从不返回null,即使所有参数都为null也不行。 Per documentation

  

忽略NULL参数。

SELECT concat(col_a, col_b);

两种备选方案的剩下的大小写 所有输入列为空,在这种情况下,我们仍然会得到一个空字符串{{1但是,有人可能想要null(至少我愿意)。一种可能的方式:

''

这会使更快的列更复杂。同样,使用SELECT CASE WHEN col_a IS NULL THEN col_b WHEN col_b IS NULL THEN col_a ELSE col_a || col_b END 但添加对特殊条件的检查:

concat()

这是如何运作的?
SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL ELSE concat(col_a, col_b) END; 是行类型表达式(col_a, col_b)的简写表示法。如果所有列为null,则行类型仅为null。详细解释:

另外,使用concat_ws()在元素(ROW (col_a, col_b) ..“和分隔符”之间添加分隔符。)


表达式与凯文的答案相似:

_ws

在PostgreSQL 8.3(没有SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state; )中准备空值是很繁琐的。一种方式(很多):

concat()

函数波动率仅为SELECT COALESCE( CASE WHEN $1.zipcode IS NULL THEN $1.city WHEN $1.city IS NULL THEN $1.zipcode ELSE $1.zipcode || ' - ' || $1.city END, '') || COALESCE(', ' || $1.state, '');

但请注意,STABLEconcat()concat_ws()函数,而不是STABLE,因为它们可以调用依赖的数据类型输出函数(如IMMUTABLE)在区域设置上。 Explanation by Tom Lane.

这禁止将它们直接用于索引表达式。如果知道结果在您的情况下实际上是不可变的,您可以使用timestamptz_out函数包装器解决此问题。示例:

答案 1 :(得分:15)

您无需存储列以便以此方式引用它。试试这个:

设置:

CREATE TABLE tbl
  (zipcode text NOT NULL, city text NOT NULL, state text NOT NULL);
INSERT INTO tbl VALUES ('10954', 'Nanuet', 'NY');

我们可以看到我们有“正确的东西”:

\pset border 2
SELECT * FROM tbl;
+---------+--------+-------+
| zipcode |  city  | state |
+---------+--------+-------+
| 10954   | Nanuet | NY    |
+---------+--------+-------+

现在添加一个带有所需“列名”的函数,该函数将表的记录类型作为唯一参数:

CREATE FUNCTION combined(rec tbl)
  RETURNS text
  LANGUAGE SQL
AS $$
  SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
$$;

这创建了一个函数,可以像使用表的列一样使用,只要指定了表名或别名,如下所示:

SELECT *, tbl.combined FROM tbl;

显示如下:

+---------+--------+-------+--------------------+
| zipcode |  city  | state |      combined      |
+---------+--------+-------+--------------------+
| 10954   | Nanuet | NY    | 10954 - Nanuet, NY |
+---------+--------+-------+--------------------+

这是有效的,因为PostgreSQL首先检查实际列,但是如果找不到一个,并且标识符用关系名称或别名限定,它会查找类似上面的函数,并以行作为其运行它参数,返回结果,好像它是一个列。如果您愿意,您甚至可以在这样的“生成列”上编制索引。

因为您没有在每行中为重复数据使用额外空间,或者在所有插入和更新上触发触发器,所以这通常比替代方案更快。

答案 2 :(得分:12)

你检查了字符串连接功能吗?类似的东西:

update table_c set column_a = column_b || column_c 

应该有效。更多here