Esta seção descreve as expressões condicionais compatíveis com o padrão SQL disponíveis no PostgreSQL.
Se suas necessidades vão além dos recursos dessas expressões condicionais, convém considerar escrever uma função do lado do servidor em uma linguagem de programação mais enunciativa.
Embora COALESCE, GREATEST
e LEAST sejam sintaticamente semelhantes a
funções, não são funções comuns, portanto não podem ser usadas
com argumentos de matriz VARIADIC.
CASE #
A expressão SQL CASE é uma
expressão condicional genérica, semelhante a instruções
if/else em outras linguagens de programação:
[83]
CASE WHENcondiçãoTHENresultado[WHEN ...] [ELSEresultado] END
As expressões CASE podem ser usadas sempre que uma
expressão for válida.
Cada condição é uma expressão que retorna
um resultado booleano.
Se o resultado da condição for verdade, o valor da expressão
CASE será o resultado que
segue a condição, e o restante da expressão CASE
não será processado.
Se o resultado da condição não for verdade, as cláusulas
WHEN subsequentes serão examinadas da mesma maneira.
Se nenhuma cláusula
WHEN condição
for verdade, o valor da expressão CASE será o
resultado da cláusula ELSE.
Se a cláusula ELSE for omitida, e nenhuma condição
resultar em verdade, o resultado será o valor nulo.
Um exemplo:
CREATE TEMPORARY TABLE teste (a integer); INSERT INTO teste VALUES (1), (2), (3); SELECT * FROM teste;
a --- 1 2 3 (3 linhas)
SELECT a,
CASE WHEN a=1 THEN 'um'
WHEN a=2 THEN 'dois'
ELSE 'outro'
END
FROM teste;
a | case ---+------- 1 | um 2 | dois 3 | outro (3 linhas)
Os tipos de dados de todas as expressões
resultado devem ser conversíveis em um
único tipo de dados de saída.
Veja a Seção 10.5 para obter mais detalhes.
Existe uma forma “simples” da expressão
CASE, que é uma variante da forma geral acima:
CASEexpressãoWHENvalorTHENresultado[WHEN ...] [ELSEresultado] END
A primeira expressão é calculada, e então
comparada com cada uma das expressões valor
nas cláusulas WHEN até encontrar um valor que seja
correspondente.
Se nenhuma correspondência for encontrada, será retornado o
resultado da cláusula ELSE
(ou o valor nulo).
Esta cláusula é semelhante ao comando switch
da linguagem C.
O exemplo acima pode ser escrito usando a sintaxe simples
da cláusula CASE:
SELECT a,
CASE a WHEN 1 THEN 'um'
WHEN 2 THEN 'dois'
ELSE 'outro'
END
FROM teste;
a | case ---+------- 1 | um 2 | dois 3 | outro (3 linhas)
A cláusula CASE não avalia nenhuma subexpressão que
não seja necessária para determinar o resultado.
Por exemplo, esta é uma maneira possível de evitar um erro de
divisão por zero:
SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;
Conforme descrito na Seção 4.2.14,
existem várias situações onde as subexpressões de uma expressão
são avaliadas em momentos diferentes, de modo que o princípio de
que “CASE avalia apenas as subexpressões
necessárias” não é imperativo.
Por exemplo, a subexpressão 1/0
geralmente irá resultar em erro de divisão por zero no momento do
planejamento, mesmo estando em uma condição da instrução
CASE que nunca seria escolhida em tempo de execução.
COALESCE #COALESCE(valor[, ...])
A função COALESCE retorna o primeiro de seus
argumentos que não for nulo.
É retornado o valor nulo somente quando todos os argumentos são nulos.
Geralmente é usada para substituir valores nulos por um valor padrão
quando os dados são recuperados para exibição, por exemplo:
[84]
SELECT COALESCE(descricao, descricao_curta, '(nenhuma)') ...
Esta consulta retorna o argumento descricao,
caso não seja nulo, senão retorna o argumento
descricao_curta, caso não seja nulo, senão
retorna (nenhuma).
Os argumentos devem ser todos conversíveis para um tipo de dados comum, que será o tipo de dados do resultado (veja a Seção 10.5 para obter detalhes).
Da mesma forma que a expressão CASE, a expressão
COALESCE avalia apenas os argumentos
necessários para determinar o resultado; ou seja, os argumentos
à direita do primeiro argumento não nulo não são avaliados.
Esta função do padrão SQL fornece recursos
semelhantes aos das funções
NVL e
IFNULL, usadas em alguns outros
sistemas de banco de dados.
NULLIF #NULLIF(valor1,valor2)
A função NULLIF retorna o valor nulo se
valor1 for igual a
valor2;
senão retorna valor1.
Pode ser usada para executar a operação inversa do exemplo
COALESCE mostrado acima:
[85]
SELECT NULLIF(valor, '(none)') ...
Neste exemplo, se valor for (none),
retorna nulo, senão retorna valor.
Os dois argumentos devem ser de tipos de dados comparáveis.
Sendo específico, os argumentos são comparados exatamente como se
tivesse sido escrito , então deve haver um
operador valor1 =
valor2= disponível.
O resultado tem o mesmo tipo de dados que o primeiro argumento —
mas há uma sutileza.
O que é realmente retornado é o primeiro argumento do operador
= implícito e, em alguns casos, o primeiro
argumento será promovido para corresponder ao tipo de dados do segundo
argumento.
Por exemplo, NULLIF(1, 2.2) resulta em
numeric, por não haver operador integer
= numeric, há apenas o operador
numeric = numeric.
Exemplo:
SELECT nullif(1, 2.2), pg_typeof(nullif(1, 2.2));
nullif | pg_typeof
--------+-----------
1 | numeric
(1 linha)
GREATEST e LEAST #GREATEST(valor[, ...])
LEAST(valor[, ...])
As funções GREATEST e LEAST
selecionam, respectivamente, o maior e o menor valor de uma lista
com qualquer número de expressões.
As expressões devem ser todas conversíveis para um tipo de dados
comum, que será o tipo de dados do resultado
(veja a Seção 10.5 para obter detalhes).
Os valores NULL na lista de argumentos são ignorados.
O resultado será NULL somente se todas as expressões
forem avaliadas como NULL.
(Isto representa um desvio do padrão SQL.
Segundo o padrão, o valor retornado será NULL
se algum argumento for NULL.
Alguns outros sistema de banco de dados se comportam desta forma.)
Exemplo 9.4. Exemplo do tradutor
Neste exemplo é feita uma comparação entre as expressões
GREATEST e LEAST
dos sistemas gerenciadores de banco de dados
PostgreSQL,
Oracle 21c e o
DB2 11.5 da IBM,
usando uma lista de letras acentuadas e uma lista de cadeias
de caracteres contendo nomes próprios.
No Oracle a comparação é binária por
padrão, mas sendo linguística se estiver definido o parâmetro
NLS_COMP como LINGUISTIC
e o parâmetro NLS_SORT tiver uma configuração
diferente de BINARY.
Desta forma, no Oracle a sessão foi
configurada usando as instruções
ALTER SESSION SET NLS_COMP = LINGUISTIC e
ALTER SESSION SET NLS_SORT = FRENCH.
No DB2 a ordenação
(collation) de um banco de dados determina como
os valores de cadeia de caracteres são comparados e ordenados.
O DB2 fornece três tipos diferentes de
ordenações para um banco de dados Unicode:
ordenação IDENTITY, ordenação com reconhecimento
de idioma e ordenação baseado em UCA
(Unicode Collation Algorithm)
sensível ao código de idioma.
[86]
Desta forma, o banco de dados do DB2
foi criado através do comando
CREATE DATABASE UTF8 COLLATE USING CLDR2701_LEN_RUS
para obter uma
ordenação baseada em algoritmo de ordenação Unicode
(UCA).
Conclusão: Com a configuração binária padrão do
Oracle, e a ordenação padrão do
DB2 IDENTITY,
os resultados obtidos para os nomes próprios diferem dos obtidos
pelo PostgreSQL, mas com a configuração
apropriada do Oracle e do
DB2 os resultados dos três sistemas
gerenciadores de banco de dados são idênticos.
SELECT LEAST('a', 'ã', 'á', 'à'); → a
SELECT GREATEST('a', 'ã', 'á', 'à'); → ã
SELECT LEAST('José', 'Josué', 'João', 'Joaquim', 'Jonas'); → João
SELECT GREATEST('José', 'Josué', 'João', 'Joaquim', 'Jonas'); → Josué
SELECT GREATEST('José', 'João', NULL, 'Joaquim', 'Jonas'); → José