Roc*_*ock 31 sql postgresql null concatenation
在PostgreSQL中,我想使用SQL语句组合两列并从中创建一个新列.
我正在考虑使用concat(...),但有更好的方法吗?
最好的方法是什么?
Erw*_*ter 68
一般来说,我同意@ kgrittn的建议.去吧.
但是要解决你的基本问题concat():concat()如果你需要处理空值,新函数很有用- 并且在你的问题和你引用的问题中都没有排除null.
如果你可以排除空值,那么好的(SQL标准)连接运算符||仍然是最好的选择,@ luis的答案就好了:
SELECT col_a || col_b;
Run Code Online (Sandbox Code Playgroud)
如果您的任何一列都可以为null,那么在这种情况下结果将为null.你可以用COALESCE:
SELECT COALESCE(col_a, '') || COALESCE(col_b, '');
Run Code Online (Sandbox Code Playgroud)
但随着更多的争论,这会很快变得乏味.这就是concat()进来的地方,即使所有参数都为null ,它也永远不会返回null.每个文件:
NULL参数被忽略.
SELECT concat(col_a, col_b);
Run Code Online (Sandbox Code Playgroud)
两个备选方案的剩余角落情况是所有输入列都为null,在这种情况下我们仍然得到一个空字符串'',但是可能需要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;
Run Code Online (Sandbox Code Playgroud)
随着更多列的快速变得越来越复杂.再次使用,concat()但添加一个检查特殊条件:
SELECT CASE WHEN (col_a, col_b) IS NULL THEN NULL
ELSE concat(col_a, col_b) END;
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?
(col_a, col_b)是行类型表达式的简写表示法ROW (col_a, col_b).如果所有列都为null,则行类型仅为null.详细说明:
另外,用于concat_ws()在元素之间添加分隔符(ws.."with separator").
像凯文的回答一样的表达:
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
Run Code Online (Sandbox Code Playgroud)
在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, '');
Run Code Online (Sandbox Code Playgroud)
STABLE但是请注意,这concat()和concat_ws()是STABLE功能,而不是IMMUTABLE因为他们可以调用的数据类型的输出函数(如timestamptz_out依赖于区域设置).汤姆莱恩的解释.
这禁止它们直接用于索引表达式.如果你知道结果在你的情况下实际上是不可变的,你可以使用IMMUTABLE函数包装器解决这个问题.这里的例子:
kgr*_*ttn 15
您不需要存储列以便以这种方式引用它.试试这个:
建立:
CREATE TABLE tbl
(zipcode text NOT NULL, city text NOT NULL, state text NOT NULL);
INSERT INTO tbl VALUES ('10954', 'Nanuet', 'NY');
Run Code Online (Sandbox Code Playgroud)
我们可以看到我们有"正确的东西":
\pset border 2
SELECT * FROM tbl;
Run Code Online (Sandbox Code Playgroud)
+---------+--------+-------+ | zipcode | city | state | +---------+--------+-------+ | 10954 | Nanuet | NY | +---------+--------+-------+
现在添加一个具有所需"列名"的函数,该函数将表的记录类型作为其唯一参数:
CREATE FUNCTION combined(rec tbl)
RETURNS text
LANGUAGE SQL
AS $$
SELECT $1.zipcode || ' - ' || $1.city || ', ' || $1.state;
$$;
Run Code Online (Sandbox Code Playgroud)
这创建了一个函数,可以像使用表的列一样使用它,只要指定了表名或别名,如下所示:
SELECT *, tbl.combined FROM tbl;
Run Code Online (Sandbox Code Playgroud)
哪个显示如下:
+---------+--------+-------+--------------------+ | zipcode | city | state | combined | +---------+--------+-------+--------------------+ | 10954 | Nanuet | NY | 10954 - Nanuet, NY | +---------+--------+-------+--------------------+
这是因为PostgreSQL首先检查实际列,但是如果找不到一个,并且标识符用关系名称或别名限定,它会查找类似上面的函数,并以行作为参数运行它,返回结果好像是一个列.如果您愿意,您甚至可以在这样的"生成列"上编制索引.
因为您没有在每行中为重复数据使用额外空间,或者在所有插入和更新上触发触发器,所以这通常比备选方案更快.
lui*_*uis 13
你检查了字符串连接功能吗?就像是:
update table_c set column_a = column_b || column_c
Run Code Online (Sandbox Code Playgroud)
应该管用.更多这里
| 归档时间: |
|
| 查看次数: |
91824 次 |
| 最近记录: |