9.2. Funções e operadores de comparação #

Estão disponíveis os operadores de comparação usuais, confome descrito na Tabela 9.1.

Tabela 9.1. Operadores de comparação

OperadorDescrição
datatype < datatypeboolean Menor que
datatype > datatypeboolean Maior que
datatype <= datatypeboolean Menor que ou igual a
datatype >= datatypeboolean Maior que ou igual a
datatype = datatypeboolean Igual
datatype <> datatypeboolean Não igual
datatype != datatypeboolean Não igual

Nota

<> é a notação do padrão SQL para não igual. != é um alias, convertido para <> em um estágio muito inicial da análise. Assim, não é possível implementar operadores != e <> que façam coisas diferentes.

Estes operadores de comparação estão disponíveis para todos os tipos de dados internos que possuem uma ordenação natural, incluindo os tipos de dados numéricos, de cadeia de caracteres e de data e hora. Além disso, matrizes, tipos de dados compostos e intervalos podem ser comparados se os tipos de dados de seus componentes forem comparáveis.

Geralmente, também é possível comparar valores de tipos de dados relacionados; por exemplo, integer > bigint funciona. Alguns casos assim são implementados diretamente por operadores de comparação de tipo-cruzado, mas se nenhum operador estiver disponível, o analisador força o tipo de dados menos geral para o tipo de dados mais geral e aplica a comparação deste último operador.

Como mostrado acima, todos os operadores de comparação são operadores binários que retornam valores do tipo de dados boolean. Portanto, expressões como 1 < 2 < 3 não são válidas (porque não existe o operador < para comparar o valor booleano com 3). Para realizar testes de intervalo devem ser usados os predicados BETWEEN mostrados abaixo.

Também existem alguns predicados de comparação, como descrito na Tabela 9.2. Eles se comportam como operadores, mas possuem uma sintaxe especial exigida pelo padrão SQL.

Tabela 9.2. Predicados de comparação

Predicado

Descrição

Exemplo(s)

datatype BETWEEN datatype AND datatypeboolean

Entre (incluindo os pontos das extremidades do intervalo).

2 BETWEEN 1 AND 3t

2 BETWEEN 3 AND 1f

datatype NOT BETWEEN datatype AND datatypeboolean

Não entre (a negação do BETWEEN).

2 NOT BETWEEN 1 AND 3f

datatype BETWEEN SYMMETRIC datatype AND datatypeboolean

Entre, após classificar os dois valores das extremidades.

2 BETWEEN SYMMETRIC 3 AND 1t

datatype NOT BETWEEN SYMMETRIC datatype AND datatypeboolean

Não entre, após classificar os dois valores das extremidades.

2 NOT BETWEEN SYMMETRIC 3 AND 1f

datatype IS DISTINCT FROM datatypeboolean

Não igual, tratando nulo como valor comparável.

1 IS DISTINCT FROM NULLt (em vez de NULL)

NULL IS DISTINCT FROM NULLf (em vez de NULL)

datatype IS NOT DISTINCT FROM datatypeboolean

Igual, tratando nulo como valor comparável.

1 IS NOT DISTINCT FROM NULLf (em vez de NULL)

NULL IS NOT DISTINCT FROM NULLt (em vez de NULL)

datatype IS NULLboolean

Testa se o valor é nulo.

1.5 IS NULLf

datatype IS NOT NULLboolean

Testa se o valor não é nulo.

'null' IS NOT NULLt

datatype ISNULLboolean

Testa se o valor é nulo (sintaxe fora do padrão).

datatype NOTNULLboolean

Testa se o valor não é nulo (sintaxe fora do padrão).

boolean IS TRUEboolean

Testa se a expressão booleana resulta em verdade.

true IS TRUEt

NULL::boolean IS TRUEf (em vez de NULL)

boolean IS NOT TRUEboolean

Testa se a expressão booleana resulta em falso ou desconhecido.

true IS NOT TRUEf

NULL::boolean IS NOT TRUEt (em vez de NULL)

boolean IS FALSEboolean

Testa se a expressão booleana resulta em falso.

true IS FALSEf

NULL::boolean IS FALSEf (em vez de NULL)

boolean IS NOT FALSEboolean

Testa se a expressão booleana resulta em verdade ou desconhecido.

true IS NOT FALSEt

NULL::boolean IS NOT FALSEt (em vez de NULL)

boolean IS UNKNOWNboolean

Testa se a expressão booleana resulta em desconhecido.

true IS UNKNOWNf

NULL::boolean IS UNKNOWNt (em vez de NULL)

boolean IS NOT UNKNOWNboolean

Testa se a expressão booleana resulta em verdade ou falso.

true IS NOT UNKNOWNt

NULL::boolean IS NOT UNKNOWNf (em vez de NULL)


O predicado BETWEEN simplifica os testes de intervalo:

a BETWEEN x AND y

equivale a

a >= x AND a <= y

Note que BETWEEN trata os valores das extremidades como incluídos no intervalo. BETWEEN SYMMETRIC é como BETWEEN, exceto não haver a exigência de que o argumento à esquerda do AND seja menor ou igual ao argumento à direita. Se não for menor, estes dois argumentos são trocados automaticamente, de modo que está sempre implícito um intervalo não vazio.

As várias formas alternativas de BETWEEN são implementadas em termos de operadores de comparação comuns, portanto funcionam para qualquer tipo de dados que possa ser comparado.

Nota

O uso do AND na sintaxe do BETWEEN cria ambiguidade com o uso do AND como operador lógico. Para resolver este problema, é permitido apenas um conjunto limitado de tipos de expressão como segundo argumento da cláusula BETWEEN. Se for necessário escrever uma subexpressão mais complexa em BETWEEN, devem ser colocados parênteses ao redor da subexpressão.

Operadores de comparação comuns produzem nulo (significando desconhecido), e não verdade ou falso, quando uma das entradas é nula. Por exemplo, 7 = NULL resulta em nulo, assim como 7 <> NULL. Quando esse comportamento não for adequado, devem ser usados os predicados IS [ NOT ] DISTINCT FROM:

a IS DISTINCT FROM b
a IS NOT DISTINCT FROM b

Para entradas não nulas, IS DISTINCT FROM é idêntico ao operador <>. Entretanto, se as duas entradas forem nulas retorna falso e, se apenas uma entrada for nula, retorna verdade. De forma semelhante, IS NOT DISTINCT FROM é idêntico a = para entradas não nulas, mas retorna verdade quando as duas entradas são nulas, e falso quando apenas uma entrada é nula. Portanto, estes predicados atuam de fato como se nulo fosse um valor de dados normal, em vez de desconhecido.

Para verificar se o valor é ou não nulo, devem ser usados os predicados

expressão IS NULL
expressão IS NOT NULL

ou os predicados equivalentes, mas fora do padrão SQL:

expressão ISNULL
expressão NOTNULL

Não escreva expressão = NULL, porque NULL não é igual a NULL. (O valor nulo representa o valor desconhecido, e não é possível saber se dois valores desconhecidos são iguais.)

Dica

Algumas aplicações podem esperar que expressão = NULL retorne verdade se a expressão resulta no valor nulo. É altamente recomendável que estas aplicações sejam modificados para ficarem em conformidade com o padrão SQL. Entretanto, se isto não puder ser feito, está disponível a variável de configuração transform_null_equals. Se esta variável estiver ativa, o PostgreSQL irá converter as cláusulas x = NULL para x IS NULL.

Se a expressão for um valor de linha, então IS NULL será verdade quando a própria expressão de linha for nula, ou quando todos os campos da linha forem nulos, enquanto IS NOT NULL será verdade quando a própria expressão de linha não é nula e todos os campos da linha não são nulos. Devido a este comportamento, IS NULL e IS NOT NULL nem sempre retornam resultados inversos para expressões com valor de linha; em particular, uma expressão com valor de linha contendo campos nulos e não nulos retorna falso para os dois testes. Por exemplo:

SELECT ROW(1,2.5,'isto é um teste') = ROW(1, 3, 'não e o mesmo');

SELECT ROW(tabela.*) IS NULL FROM tabela;  -- detecta linhas inteiramente nulas

SELECT ROW(tabela.*) IS NOT NULL FROM tabela;  -- detecta todas as linhas não nulas

SELECT NOT(ROW(tabela.*) IS NOT NULL) FROM TABELA; -- detecta pelo menos um valor nulo nas linhas

Em alguns casos, pode ser preferível escrever linha IS DISTINCT FROM NULL ou linha IS NOT DISTINCT FROM NULL, que apenas verifica se o valor global da linha é nulo sem nenhum teste adicional nos campos da linha.

Os valores booleanos também podem ser testados usando os predicados:

expressão_booleana IS TRUE
expressão_booleana IS NOT TRUE
expressão_booleana IS FALSE
expressão_booleana IS NOT FALSE
expressão_booleana IS UNKNOWN
expressão_booleana IS NOT UNKNOWN

Estes sempre retornam verdade ou falso, nunca o valor nulo, mesmo quando o operando for nulo. Uma entrada nula é tratada como o valor lógico desconhecido. Note que IS UNKNOWN e IS NOT UNKNOWN são de fato idênticos a IS NULL e IS NOT NULL, respectivamente, exceto pela expressão de entrada que deve ser do tipo de dados booleano.

Também estão disponíveis algumas funções relacionadas à comparação, como descrito na Tabela 9.3.

Tabela 9.3. Funções de comparação

Função

Descrição

Exemplo(s)

num_nonnulls ( VARIADIC "any" ) → integer

Retorna o número de argumentos não nulos.

num_nonnulls(1, NULL, 2)2

num_nulls ( VARIADIC "any" ) → integer

Retorna o número de argumentos nulos.

num_nulls(1, NULL, 2)1