¿Cómo concatenar columnas en un Postgres SELECT?

145

Tengo dos columnas de cadena ay ben una tabla foo.

select a, b from foodevuelve valores ay b. Sin embargo, la concatenación de ay bno funciona. Lo intenté :

select a || b from foo

y

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

Actualización de comentarios: ambas columnas son de tipo character(2).

Alex
fuente
... u otro texttipo?
PM 77-1
@acfrancis Como OP dice concatenateque dudo que esté tratando con tipos numéricos, aunque PostgreSQL también se encargaría de algunos de ellos. Ver aquí: postgresql.org/docs/9.1/static/functions-string.html
PM 77-1
Sí, estas columnas son caracteres (2). "+" no funciona: "Ningún operador coincide con el nombre y los tipos de argumento. Es posible que deba agregar conversiones de tipo explícito".
Alex
¿Qué versión de PostgreSQL? Aquí hay documentos para 9.1: postgresql.org/docs/9.1/static/functions-string.html . Vea mi ejemplo: sqlfiddle.com/#!15/d41d8/182
PM 77-1
Probablemente tenga un error de sintaxis en su consulta no relacionado con la concatenación.
PM 77-1

Respuestas:

260

Con columnas de tipo cadena como character(2)(como mencionó más adelante), la concatenación mostrada simplemente funciona porque, citando el manual:

[...] el operador de concatenación de cadenas ( ||) acepta entradas sin cadenas, siempre que al menos una entrada sea de tipo cadena , como se muestra en la Tabla 9.8 . Para otros casos, inserte una coerción explícita para text[...]

El énfasis en negrita es mío. El segundo ejemplo ( select a||', '||b from foo) funciona para cualquier tipo de datos, ya que el literal de cadena sin tipo ', 'predeterminado es el tipo que texthace válida toda la expresión en cualquier caso.

Para los tipos de datos que no son cadenas, puede "arreglar" la primera instrucción enviando al menos un argumento a text. ( Cualquier tipo puede ser enviado a text):

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

A juzgar por su propia respuesta , se suponía que " no funciona " significaba " devuelve NULL ". El resultado de cualquier cosa concatenada a NULL es NULL. Si los valores NULL pueden estar involucrados y el resultado no debe ser NULL, úselo concat_ws()para concatenar cualquier número de valores (Postgres 9.1 o posterior):

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

O concat()si no necesitas separadores:

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

No es necesario utilizar tipos de conversión aquí, ya que ambas funciones toman "any"entrada y trabajan con representaciones de texto.

Más detalles (y por qué COALESCEes un pobre sustituto) en esta respuesta relacionada:

En cuanto a la actualización en el comentario

+no es un operador válido para la concatenación de cadenas en Postgres (o SQL estándar). Es una idea privada de Microsoft agregar esto a sus productos.

Casi no hay una buena razón para usar character(n)(sinónimo:) char(n). Use textovarchar . Detalles:

Erwin Brandstetter
fuente
Gracias. La primera versión no funciona con nulo y la segunda me dio el error para concat_ws: ninguna función coincide con el nombre dado y los tipos de argumento. Es posible que deba agregar conversiones de tipo explícito.
Alex
1
Viste Postgres 9.1 or later, ¿verdad? Para empezar, debería haber proporcionado su versión de Postgres, en la pregunta . Por favor, actualice su pregunta con toda la información solicitada, antes de volver para otra cosa.
Erwin Brandstetter
Gracias, la solución que encontré funciona para cualquier versión de Postgres
Alex
SELECT concat(a, b) FROM foo;funciona para mí en Postgres 9.3 cuando ay bson VARCHARs.
Eliminado
Gracias por su respuesta, resolvió mi problema :).
ashwaqar
33

El problema estaba en nulos en los valores; entonces la concatenación no funciona con nulos. La solución es la siguiente:

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

es mejor usar la función CONCAT en PostgreSQL para la concatenación

p.ej : select CONCAT(first_name,last_name) from person where pid = 136

si está utilizando column_a || '' || column_b para concatenación para 2 columnas, si alguno de los valores en column_a o column_b es nulo, la consulta devolverá un valor nulo. que puede no ser preferido en todos los casos ... así que en lugar de esto

||

utilizar

CONCAT

devolverá un valor relevante si alguno de ellos tiene valor

arjun nagathankandy
fuente
7

Las funciones CONCAT a veces no funcionan con versiones anteriores de postgreSQL

vea lo que solía resolver un problema sin usar CONCAT

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

O también puedes usar

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

en el segundo caso utilicé comillas dobles para first_name y last_name

Espero que esto sea útil, gracias

Rameshwar Vyevhare
fuente
1
si mi nombre o apellido es nulo, el valor de concat también muestra nulo
Lokesh
2

Como también estaba atrapado en esto, creo que debería compartir la solución que mejor funcionó para mí. También creo que esto es mucho más simple.

Si usa el nombre de la tabla en mayúscula.

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

Si usa el nombre de la tabla en minúsculas

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

¡Eso es!. Como PGSQL cuenta Double Quote para la declaración de columna y Single Quote para string, esto funciona de maravilla.

Rakib Uddin
fuente
1

Marco Laravel de PHP, estoy usando el nombre de búsqueda, el apellido Los campos se consideran como Búsqueda de nombre completo

Usando || símbolo O métodos 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);

Esto funcionó encanto !!!

venkatskpi
fuente
0

Prueba esto

select textcat(textcat(FirstName,' '),LastName) AS Name from person;
Muhammad Sadiq
fuente
8
concat_ws(' ', FirstName, LastName)Sería mucho más limpio.
a_horse_with_no_name
-1

Por ejemplo, si hay una tabla de empleados que consta de columnas como:

employee_number,f_name,l_name,email_id,phone_number 

si queremos concatenar f_name + l_namecomo name.

SELECT employee_number,f_name ::TEXT ||','|| l_name::TEXT  AS "NAME",email_id,phone_number,designation FROM EMPLOYEE;
Abhishek Mitra
fuente
¿Qué agrega esta respuesta sobre las respuestas existentes?
Erwin Brandstetter