在PostgreSQL,我想使用一个SQL语句来两列合并,并从他们创造一个新列。
我在考虑使用concat(...)
但有没有更好的办法?
什么是做到这一点的最好方法是什么?
在PostgreSQL,我想使用一个SQL语句来两列合并,并从他们创造一个新列。
我在考虑使用concat(...)
但有没有更好的办法?
什么是做到这一点的最好方法是什么?
一般情况下,我同意@ kgrittn的建议 。 去吧。
但是,解决您在基本问题concat()
新功能concat()
如果你需要处理空值是有用的-和空既没有在你的问题也不在你指的是一个被排除在外。
如果你能排除空值,历久弥新(SQL标准)连接操作符||
仍然是最好的选择,而@luis的回答仅仅是罚款:
SELECT col_a || col_b;
如果您的任一列可以为空,其结果将是在这种情况下空。 你可以用防守COALESCE
:
SELECT COALESCE(col_a, '') || COALESCE(col_b, '');
但是,这容易让人觉得无聊与更多的参数。 这就是concat()
到来时, 从未返回null,不即使所有参数都为空。 每文档 :
NULL参数被忽略。
SELECT concat(col_a, col_b);
余下的角落情况下这两种选择是所有输入字段为空在这种情况下,我们仍然得到一个空字符串''
,但有可能要空,而不是(至少我会)。 一种可能的方式:
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)
为行类型表达式简化符号ROW (col_a, col_b)
如果所有字段为空的行类型只是空。 详细说明:
此外,使用concat_ws()
到元件(之间添加分隔符_ws
..“与分隔符”)。
像在凯文的答案的表达式:
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
是乏味用于在PostgreSQL的8.3空值准备(没有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, '');
STABLE
但是请注意,是concat()
和concat_ws()
是STABLE
的功能,而不是IMMUTABLE
因为他们可以调用的数据类型的输出函数(如timestamptz_out
)依赖于区域设置。 由汤姆巷解释。
这禁止在索引表达式其直接使用。 如果你知道这个结果是在你的情况实际上是不可变的,你可以解决这个与IMMUTABLE
函数包装。 这里的例子:
你并不需要存储的列参考这种方式。 试试这个:
建立:
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的第一个检查的实际列,但如果一个也没有找到,且标识符是合格的有关系的名称或别名,它看起来像上面的功能,并与该行作为参数运行它,返回结果就好像它是一列。 你甚至可以在这样的“生成列”的索引,如果你想这样做。
因为你不是每一行中使用额外的空间用于复制数据,或射击触发所有插入和更新,这往往比其它可供选择快。
你是否检查了字符串连接功能? 就像是:
update table_c set column_a = column_b || column_c
应该管用。 更多在这里