Como concatenar colunas em um Postgres SELECT?


145

Eu tenho duas colunas de string ae bem uma tabela foo.

select a, b from fooretorna valores ae b. No entanto, concatenação ae bnão funciona. Eu tentei :

select a || b from foo

e

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

Atualização de comentários: as duas colunas são do tipo character(2).


... ou outro texttipo?
PM 77-1 13/11/2013

@acfrancis Desde que o OP diz concatenateque duvido que ele esteja lidando com tipos numéricos, embora o PostgreSQL também cuide de alguns deles. Veja aqui: postgresql.org/docs/9.1/static/functions-string.html
PM 77-1 13/13

Sim, essas colunas são caracteres (2). "+" não funciona - "Nenhum operador corresponde ao nome e tipo (s) de argumento. Você pode precisar adicionar conversões de tipo explícitas."
Alex13:

Qual versão do PostgreSQL? Aqui estão os documentos para 9.1: postgresql.org/docs/9.1/static/functions-string.html . Veja meu exemplo: sqlfiddle.com/#!15/d41d8/182
PM 77-1 13/13

Você provavelmente tem um erro de sintaxe na sua consulta não relacionado à concatenação.
PM 77-1

Respostas:


260

Com colunas do tipo string, como character(2)(como você mencionou mais adiante), a concatenação exibida funciona porque, citando o manual:

[...] o operador de concatenação de strings ( ||) aceita entrada sem strings, desde que pelo menos uma entrada seja de um tipo de string , conforme mostrado na Tabela 9.8 . Para outros casos, insira uma coerção explícita para text[...]

Negrito ênfase minha. O segundo exemplo ( select a||', '||b from foo) funciona para todos os tipos de dados, já que o literal da cadeia de caracteres sem ', 'tipo padroniza o tipo, texttornando a expressão inteira válida em qualquer caso.

Para tipos de dados que não são de cadeia, você pode "consertar" a 1ª declaração lançando pelo menos um argumento para text. ( Qualquer tipo pode ser convertido para text):

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

A julgar pela sua própria resposta , " não funciona " deveria significar " retorna NULL ". O resultado de qualquer coisa concatenada para NULL é NULL. Se valores NULL puderem estar envolvidos e o resultado não for NULL, use concat_ws()para concatenar qualquer número de valores (Postgres 9.1 ou posterior):

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

Ou concat()se você não precisar de separadores:

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

Não há necessidade de conversão de tipos aqui, pois ambas as funções recebem "any"entrada e trabalham com representações de texto.

Mais detalhes (e por que COALESCEé um substituto ruim) nesta resposta relacionada:

Em relação à atualização no comentário

+não é um operador válido para concatenação de strings no Postgres (ou SQL padrão). É uma idéia particular da Microsoft adicionar isso a seus produtos.

Não há praticamente nenhuma boa razão para usar character(n)(sinônimo:char(n) . Use textouvarchar . Detalhes:


Obrigado. A primeira versão não funciona com nulo e a segunda deu o erro para concat_ws: nenhuma função corresponde ao nome e aos tipos de argumento. Pode ser necessário adicionar conversões de tipo explícitas.
Alex

1
Você viu Postgres 9.1 or later, certo? Você deveria ter fornecido sua versão do Postgres para começar, na pergunta . Por favor, atualizar a sua pergunta com toda a informação solicitada, antes de voltar para qualquer outra coisa.
Erwin Brandstetter

Obrigado, a solução que eu encontrei funciona para qualquer versão Postgres
Alex

SELECT concat(a, b) FROM foo;funciona para mim no Postgres 9.3 quando ae bsão VARCHARs.
Elimisteve

Obrigado pela sua resposta, resolveu o meu problema :).
Ashwaqar

33

O problema estava em valores nulos; a concatenação não funciona com nulos. A solução é a seguinte:

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

18

é melhor usar a função CONCAT no PostgreSQL para concatenação

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

se você estiver usando column_a || '' || column_b para concatenação para 2 colunas, se algum valor em column_a ou column_b for nulo, a consulta retornará valor nulo. que pode não ser preferido em todos os casos.

||

usar

CONCAT

retornará valor relevante se um deles tiver valor


7

As funções do CONCAT às vezes não funcionam com a versão mais antiga do postgreSQL

ver o que eu usei para resolver o problema sem usar o CONCAT

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

Ou também você pode usar

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

no segundo caso, usei aspas duplas para first_name e last_name

Espero que isso seja útil, obrigado


1
se meu nome ou sobrenome for nulo, concat value também mostrando null
Lokesh

2

Como eu também estava preso nisso, acho que deveria compartilhar a solução que funcionou melhor para mim. Eu também acho que isso é muito mais simples.

Se você usar o nome da tabela em maiúscula.

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

Se você usar o nome da tabela em minúsculas

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

É isso aí!. Como o PGSQL conta aspas duplas para declaração de coluna e aspas simples para string, isso funciona como um encanto.


1

No framework Laravel do PHP, estou usando a pesquisa first_name, last_name Os campos consideram como Pesquisa por nome completo

Usando || símbolo Ou 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);

Este charme funcionou !!!



-1

Por exemplo, se houver uma tabela de funcionários que consiste em colunas como:

employee_number,f_name,l_name,email_id,phone_number 

se 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;

O que essa resposta adiciona sobre as respostas existentes?
Erwin Brandstetter
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.