Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Lidando com NULLs no SQL Server


O que é NULO? NULL ou o marcador NULL é a forma como representamos um valor desconhecido no SQL, por SQL estou me referindo ao padrão Structured Query Language, não ao MS SQL Server. A última frase nos leva um pouco de volta a 1969, quando o padrão foi definido pela primeira vez pelo Dr. E.F. Codd. NULL torna-se necessário porque precisamos pensar em termos do que é chamado de lógica de predicados de três valores. Um predicado é a propriedade de uma expressão que é válida ou não. Pelo valor de face, alguém pensaria em duas possibilidades:VERDADEIRO ou FALSO. No entanto, existe uma terceira possibilidade:DESCONHECIDA.

Vamos dar um exemplo. Assumindo que um atributo (coluna) em nossa relação (Tabela) representa o Número de Identificação Fiscal (TIN) de um conjunto de proprietários de pequenas empresas em Accra, Gana. A coluna do registro de cada proprietário de empresa será preenchida com seu TIN e podemos usar essa coluna para determinar algum outro atributo, como se ele está em dia com os pagamentos de impostos. No entanto, existem duas possibilidades extras neste caso de uso:
  1. O proprietário da empresa tem um NIF e está atualizado.
  2. O proprietário da empresa não tem um TIN e (obviamente) não está atualizado.

A descrição acima descreve o que o Dr. Codd chamou de lógica de predicados de quatro valores. O padrão SQL, no entanto, simplifica essas duas condições adicionais, definindo-o como desconhecido, ou seja, NULL. Não sabemos o TIN do proprietário da empresa e não podemos determinar nenhum outro valor do atributo do proprietário da empresa afetado. Portanto, NULL é DESCONHECIDO e é o terceiro valor na lógica de predicado de três valores padrão.

NULL é especial


A definição de NULL exige o tratamento do marcador de forma diferente dos valores reais. Seguem exemplos:
  1. Não existe o filtro “WHERE =NULL;”. A expressão correta seria “WHERE IS NULL;”. O mesmo vale para a expressão inversa.
  2. Ao classificar o SQL em ordem crescente, você pode optar por listar os NULLs primeiro ou por último. O padrão é listar os NULLs primeiro.
  3. Você não pode comparar valores NULL. Isso deve ser óbvio, pois dissemos que NULL é DESCONHECIDO.
  4. Quando uma tentativa de concatenação envolve uma coluna NULL, o resultado é NULL.

Funções comuns relacionadas a NULL


A seguir estão três funções comuns relacionadas a NULL no SQL Server

ISNULO

ISNULL – Substitui NULL por um valor de substituição especificado. A Listagem 1 e a Figura 1 mostram exemplos simples de ISNULL.
-- Listing 1: Simple Example of ISSNULL
SELECT ISNULL (NULL, 3) NULLREPLACEMENT;
SELECT ISNULL (NULL,'GREEN') NULLREPLACEMENT;
SELECT ISNULL (NULL,'2018-12-25') NULLREPLACEMENT;

Fig 1:Exemplo Simples de ISNULL

NULLIF

NULLIF retorna NULL é o valor dos dois argumentos são iguais.
-- Listing 2: Simple Example of NULLIF
SELECT NULLIF(3,3) AS NULLIFF;
SELECT NULLIF(3,5) AS NULLIFF;
SELECT NULLIF('RED','RED') AS NULLIFF;
SELECT NULLIF('GREEN','RED') AS NULLIFF;

Fig. 2:Exemplo Simples de NULLIF

COALESCE

COALESCE retorna o primeiro valor não NULL da lista fornecida. A Listagem 1 mostra exemplos disso e a Figura 1 mostra a saída das consultas.
-- Listing 3: Simple Example of COALESCE
SELECT COALESCE (NULL,'','GREEN','','') AS NULLRESPONSE;
SELECT COALESCE (NULL,'GREEN','HOPE','') AS NULLRESPONSE;
SELECT COALESCE (1,'','GREEN','','') AS NULLRESPONSE;

Fig 3:Exemplo Simples de Coalescência

Observe que esses exemplos simples expõem o uso da natureza de NULL. NULL e espaço em branco NÃO é o mesmo. Na primeira instrução, COALESCE retorna um espaço em branco mostrando que um espaço em branco é o primeiro valor não NULL na lista.

Diferenças entre ISNULL e COALESCE


As diferenças entre ISNULL e COALESCE tem sido objeto de vários artigos online, bem como livros como os listados na seção de referências. Essas diferenças são resumidas a seguir:
  1. ISNULL é proprietário do SQL Server enquanto COALESCE é uma função padrão ANSI. Isso implica que, para portabilidade, o COALESCE é o preferido.
  2. ISNULL aceita apenas dois argumentos, enquanto COALESCE pode receber mais de dois argumentos.
  3. O tipo de dados do valor retornado por ISNULL é determinado pelo tipo de dados do primeiro argumento, enquanto o tipo de dados do valor retornado por COALESCE é determinado pelo tipo de dados na lista com a precedência mais alta.
  4. Quando ambas as funções são usadas com subconsultas, ISNULL funciona melhor porque COALESCE é traduzido internamente para uma expressão CASE, fazendo com que ele tenda a repetir varreduras.

Itzik Ben-Gan também explora outras implicações da conversão de COALESCE para uma expressão de caso em seu artigo, cujo link é fornecido no final deste artigo.

Exemplos de casos de uso


Queremos exibir em um portal da web a lista de clientes com base em determinados critérios da tabela que estamos criando na Listagem 4. As tarefas 1 e 2 fornecem possíveis requisitos e usamos ISNULL e COALESCE para atender aos requisitos.
--Listing 4: Table Creation Script
CREATE TABLE CUSTOMER 
(ID INT IDENTITY (1,1)
,FIRSTNAME VARCHAR(50)
,LASTNAME VARCHAR(50)
,SEX CHAR(1)
,ADDRESS VARCHAR(300)
,FIRSTTRANDATE DATETIME
,PHONENUMBER1 BIGINT
,PHONENUMBER2 BIGINT
,PHONENUMBER3 BIGINT);
GO

INSERT INTO CUSTOMER VALUES ('KENNETH','IGIRI','M','ACCRA, GHANA',GETDATE(),'0245335678','0555335678',NULL);
INSERT INTO CUSTOMER VALUES ('RICHARD','HANO','M','BUDAPEST, HUNGARY',GETDATE(),'889189400122',NULL,NULL);
INSERT INTO CUSTOMER VALUES ('GEORGINA','APPIAH','F','ACCRA, GHANA','09-16-2018','02456665678','0275339678',NULL);
INSERT INTO CUSTOMER VALUES ('HOWARD','KLEVIA',NULL,'HAGUE, SWITZERLAND','02-16-2017','3499285782',NULL,NULL);
INSERT INTO CUSTOMER VALUES ('ZEN','GREGOR',NULL,'SHANGHAI, CHINA','06-23-2018','0245335678','0555335678',NULL);
INSERT INTO CUSTOMER VALUES ('IHEOMA','AWA','F','LAGOS, NIGERIA',GETDATE(),'0245335678','0555335678',NULL);

Fig. 4 Tabela de Amostra

Tarefa 1 :retorna a lista de todos os clientes que não forneceram um número de telefone alternativo.
--Listing 5: Table List of Customers with no Secondary Phones
--A: The Simple Answer
SELECT * FROM CUSTOMER WHERE PHONENUMBER2 IS NULL ;

--B: Presenting the Result Set Better
SELECT 
FIRSTNAME
,LASTNAME
,ADDRESS
,FIRSTTRANDATE
,PHONENUMBER1 AS [PRIMARY PHONE NUMBER]
,ISNULL(CAST(PHONENUMBER2 AS VARCHAR), 'NO SECONDARY PHONE') AS [SECONDARY PHONE NUMBER]
FROM CUSTOMER WHERE PHONENUMBER2 IS NULL ;

Usando COALESCE (ou ISNULL), podemos apresentar as informações necessárias muito melhor usando um texto que diz 'Sem telefone secundário'.

Fig. 5 Conjunto de resultados para a Listagem 5

Tarefa 2 :retorna a lista de todos os clientes, seu número de telefone principal, e qualquer outro número de telefone alternativo.
--Listing 6: Table List of Customers with an Other Alternate Number
SELECT 
FIRSTNAME
,LASTNAME
,ADDRESS
,FIRSTTRANDATE
,PHONENUMBER1 AS [PRIMARY PHONE NUMBER]
,COALESCE(CAST(PHONENUMBER2 AS VARCHAR),CAST(PHONENUMBER3 AS VARCHAR), 'NO OTHER PHONE') AS [OTHER PHONE NUMBER]
FROM CUSTOMER  ;

Fig. 6 Conjunto de resultados para a Listagem 6

Nesse caso, ISNULL não é uma opção, pois estamos passando três argumentos.

Conclusão


Neste artigo, discutimos o conceito de NULL no que se refere à lógica de predicado de três valores e descrevemos funções populares que usamos no SQL Server para lidar com conjuntos de dados contendo NULLs. Também vimos exemplos de como essas funções podem ser usadas. Muitas outras referências se aprofundam no uso, benefícios e limitações dessas funções. Eu recomendo os livros e blogs de Itzik Ben-Gan como boas fontes de informação.

Referências

  • NULLIF (Transact-SQL)
  • COALESCE (Transact-SQL)
  • Artigo de Itzik Ben-Gan