226

I have two string columns a and b in a table foo.

select a, b from foo returns values a and b. However, concatenation of a and b does not work. I tried :

select a || b from foo

and

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

Update from comments: both columns are type character(2).

6
  • ... or another text type?
    – PM 77-1
    Commented Nov 13, 2013 at 0:31
  • 1
    @acfrancis Since OP says concatenate I doubt that he's dealing with numeric types, though PostgreSQL would take care of some of them as well. See here:postgresql.org/docs/9.1/static/functions-string.html
    – PM 77-1
    Commented Nov 13, 2013 at 0:34
  • 1
    Yes, these columns are character(2). "+" does not work - " No operator matches the given name and argument type(s). You might need to add explicit type casts."
    – Alex
    Commented Nov 13, 2013 at 0:35
  • 1
    What version of PostgreSQL? Here are docs for 9.1: postgresql.org/docs/9.1/static/functions-string.html. See my example: sqlfiddle.com/#!15/d41d8/182
    – PM 77-1
    Commented Nov 13, 2013 at 0:38
  • You probably have a syntax error in your query not related to concatenation.
    – PM 77-1
    Commented Nov 13, 2013 at 0:40

9 Answers 9

358

With string types (including character(2)), the displayed concatenation just works because, quoting the manual:

[...] the string concatenation operator (||) accepts non-string input, so long as at least one input is of a string type, as shown in Table 9.8. For other cases, insert an explicit coercion to text [...]

Bold emphasis mine. The 2nd example select a||', '||b from foo works for any data types because the untyped string literal ', ' defaults to type text making the whole expression valid.

For non-string data types, you can "fix" the 1st statement by casting at least one argument to text. Any type can be cast to text.

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

Judging from your own answer, "does not work" was supposed to mean "returns null". The result of anything concatenated to null is null. If null values can be involved and the result shall not be null, use concat_ws() to concatenate any number of values:

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

Separators are only added between non-null values, i.e. only where necessary.

Or concat() if you don't need separators:

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

No need for type casts since both functions take "any" input and work with text representations. However, that's also why the function volatility of both concat() and concat_ws() is only STABLE, not IMMUTABLE. If you need an immutable function (like for an index, a generated column, or for partitioning), see:

More details (and why COALESCE is a poor substitute) in this related answer:

Asides

+ (as mentioned in comments) is not a valid operator for string concatenation in Postgres (or standard SQL). It's a private idea of Microsoft to add this to their products.

There is hardly any good reason to use character(n) (synonym: char(n)). Use text or varchar. Details:

4
  • Thank you. The 1st version does not work with null and the 2nd gave me the error for concat_ws: No function matches the given name and argument types. You might need to add explicit type casts.
    – Alex
    Commented Nov 13, 2013 at 16:10
  • 1
    You did see Postgres 9.1 or later, right? You should have provided your version of Postgres to begin with, in the question. Please update your question with all the requested information, before you come back for anything else. Commented Nov 13, 2013 at 16:27
  • Thank you, the solution I found works for any Postgres version
    – Alex
    Commented Nov 19, 2014 at 16:35
  • SELECT concat(a, b) FROM foo; works for me in Postgres 9.3 when a and b are VARCHARs.
    – elimisteve
    Commented Feb 3, 2015 at 1:27
51

The problem was in nulls in the values; then the concatenation does not work with nulls. The solution is as follows:

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

it is better to use CONCAT function in PostgreSQL for concatenation

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

if you are using column_a || ' ' || column_b for concatenation for 2 column , if any of the value in column_a or column_b is null query will return null value. which may not be preferred in all cases.. so instead of this

||

use

CONCAT

it will return relevant value if either of them have value

2
  • 3
    Worked for me. Happily found I could add a space between too: CONCAT(first_name, ' ', last_name) Commented Nov 24, 2020 at 19:00
  • this should be the right answer because concat accepts null
    – Cocuba
    Commented Sep 10, 2021 at 10:17
14

As i was also stuck in this, think i should share the solution that worked best for me. I also think that this is much simpler.

If you use Capitalized table name.

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

If you use lowercase table name

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

That's it!. As PGSQL counts Double Quote for column declaration and Single Quote for string, this works like a charm.

1
  • If there can be NULL values, this expression produces a leading or trailing space. Typically not what you want. Use concat_ws() instead. Commented Feb 26, 2021 at 11:36
12

CONCAT functions sometimes not work with older postgreSQL version

see what I used to solve problem without using CONCAT

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

Or also you can use

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

in second case I used double quotes for first_name and last_name

Hope this will be useful, thanks

1
  • 1
    if my first name or last name is null then concat value also showing null
    – Lokesh
    Commented Aug 28, 2018 at 6:00
0

PHP's Laravel framework, I am using search first_name, last_name Fields consider like Full Name Search

Using || symbol Or concat_ws(), concat() methods

$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);

This worked charm!!!

0

Try this

select concat_ws(' ', FirstName, LastName) AS Name from person;
1
  • 9
    concat_ws(' ', FirstName, LastName) would be much cleaner.
    – user330315
    Commented Nov 13, 2015 at 10:19
-2

For example if there is employee table which consists of columns as:

employee_number,f_name,l_name,email_id,phone_number 

if we want to concatenate f_name + l_name as name.

SELECT employee_number,f_name ::TEXT ||','|| l_name::TEXT  AS "NAME",email_id,phone_number,designation FROM EMPLOYEE;
1
  • What does this answer add over existing answers? Commented Dec 16, 2017 at 16:53
-2

You can also use a pipe for this operation.

Select EmployeeID ,FirstName ||' ' || LastName as Full_Name from Employees
order by EmployeeID
1
  • This does not answer the question. Nor does it add anything useful. Commented Apr 11, 2023 at 2:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.