如何连接Postgres SELECT中的列?


145

我有两个字符串列ab一个表foo

select a, b from foo返回值ab。但是,串联ab不起作用。我试过了 :

select a || b from foo

select  a||', '||b from foo

从注释更新:两列均为type character(2)


...还是其他text类型?
下午77-1,0

@acfrancis自从OP说concatenate我怀疑他正在处理数字类型,尽管PostgreSQL也将处理其中的一些。看到这里:postgresql.org/docs/9.1/static/functions-string.html
PM 77-1

是的,这些列是character(2)。“ +”不起作用-“没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。”
亚历克斯

什么版本的PostgreSQL?以下是9.1的文档:postgresql.org/docs/9.1/static/functions-string.html。参见我的示例:sqlfiddle.com/#
PM 77-1

您的查询中可能有语法错误,与连接无关。
下午77-1,0

Answers:


260

对于类似字符串类型的character(2)(如您稍后所述),显示的连接仅能起作用,因为引用了该手册:

字符串连接运算符(||)接受非字符串输入,只要至少一个输入为字符串类型即可,如表9.8所示 。对于其他情况,请在text[...]上插入显式强制

大胆强调我的。第二个示例(select a||', '||b from foo)适用于任何数据类型,因为未类型化的字符串文字', '默认为text在任何情况下都使整个表达式有效的类型。

对于非字符串数据类型,您可以通过强制转换来“修复”第一条语句至少一个参数为text。(可以将任何类型强制转换为text):

SELECT a::text || b AS ab FROM foo;

您自己的答案来看,“ 不起作用 ”应该表示“ 返回NULL ”。任何串联为NULL 的结果都是NULL。如果可以包含NULL值并且结果不得为NULL,请使用concat_ws()串联任意数量的值(Postgres 9.1或更高版本):

SELECT concat_ws(', ', a, b) AS ab FROM foo;

或者,concat()如果您不需要分隔符:

SELECT concat(a, b) AS ab FROM foo;

由于两个函数都接受"any"输入并使用文本表示,因此这里不需要类型转换。

COALESCE在此相关答案中有更多详细信息(以及为什么不能替代):

关于更新 评论中的

+在Postgres(或标准SQL)中不是有效的字符串连接运算符。将其添加到他们的产品是Microsoft的一个私人想法。

几乎没有任何理由使用character(n)(同义词:)char(n)。使用textvarchar。细节:


谢谢。第一个版本不适用于null,第二个版本给我concat_ws错误:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。
亚历克斯

1
你看到了Postgres 9.1 or later吧?您应该提供与你的Postgres的版本开始,在这一问题。请更新您的问题与要求的所有资料,你回来之前别的。
Erwin Brandstetter

谢谢您,我发现的解决方案适用于任何Postgres版本
Alex

SELECT concat(a, b) FROM foo;abVARCHARs 时在Postgres 9.3中为我工作。
elimisteve

谢谢您的回答,它解决了我的问题:)。
阿什瓦卡

33

问题在于值是否为空;则串联不能与null一起使用。解决方法如下:

SELECT coalesce(a, '') || coalesce(b, '') FROM foo;

18

最好在PostgreSQL中使用CONCAT函数进行串联

例如: select CONCAT(first_name,last_name) from person where pid = 136

如果您使用的是column_a || ''|| column_b用于2列的串联,如果column_a或column_b中的任何值为null,查询将返回null值。并非在所有情况下都是首选。

||

康卡特

如果其中任何一个有值,它将返回相关值


7

CONCAT函数有时不适用于较旧的postgreSQL版本

看看我不使用CONCAT来解决问题的方法

 u.first_name || ' ' || u.last_name as user,

或者你也可以使用

 "first_name" || ' ' || "last_name" as user,

在第二种情况下,我对first_name和last_name使用双引号

希望这会有用,谢谢


1
如果我的名字或姓氏为null,则concat值也显示为null
Lokesh

2

由于我也陷入了困境,所以我应该分享最适合我的解决方案。我也认为这要简单得多。

如果使用大写的表名。

SELECT CONCAT("firstName", ' ', "lastName") FROM "User"

如果使用小写表名

SELECT CONCAT(firstName, ' ', lastName) FROM user

而已!。由于PGSQL将“双引号”用于列声明并将“单引号”视为字符串,所以它的工作原理就像是一种魅力。


1

PHP的Laravel框架, 我使用的是搜索first_name,last_name字段像全名搜索一样考虑

使用|| symbol或concat_ws(),concat()方法

$names = str_replace(" ", "", $searchKey);                               
$customers = Customer::where('organization_id',$this->user->organization_id)
             ->where(function ($q) use ($searchKey, $names) {
                 $q->orWhere('phone_number', 'ilike', "%{$searchKey}%"); 
                 $q->orWhere('email', 'ilike', "%{$searchKey}%");
                 $q->orWhereRaw('(first_name || last_name) LIKE ? ', '%' . $names. '%');
    })->orderBy('created_at','desc')->paginate(20);

这行得通的魅力!!!



-1

例如,如果存在员工表,该表由以下各列组成:

employee_number,f_name,l_name,email_id,phone_number 

如果我们想串联f_name + l_namename

SELECT employee_number,f_name ::TEXT ||','|| l_name::TEXT  AS "NAME",email_id,phone_number,designation FROM EMPLOYEE;

这个答案加上现有答案有什么?
Erwin Brandstetter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.