Database
 sql >> Base de Dados >  >> RDS >> Database

Um uso prático da função SQL COALESCE


Este artigo fala sobre o uso prático da função SQL COALESCE em alguns cenários da vida profissional. Ele destaca a importância do uso correto e em tempo hábil desta função para resolver os problemas relacionados ao banco de dados.

Além disso, implementaremos as etapas específicas necessárias para resolver os problemas com a ajuda desta função.

Pré-requisitos


Antes de se preparar para revisar e implementar os próximos exemplos deste artigo, é altamente recomendável se familiarizar com os seguintes problemas:
  • Noções básicas de T-SQL . Os leitores devem estar bem cientes dos scripts T-SQL. Além disso, eles precisam escrever e executar consultas SQL em bancos de dados de amostra confortavelmente.
  • Noções básicas da função COALESCE . Os leitores precisam estar familiarizados com este campo. Se você precisar das informações para estudá-las, consulte o artigo SQL COALESCE Function Handling NULL Values ​​Effectively .

Banco de dados de amostra


Configure um banco de dados de exemplo chamado CoalesceUseDB do seguinte modo:
-- Setup sample database
Create DATABASE CoalesceUseDB;
GO

Como alternativa, você pode executar consultas no tempdb banco de dados se preferir fazê-lo.

Considerações sobre o uso prático


Vamos revisar dois casos de uso práticos da função COALESCE. Devemos ter em mente que o objetivo principal desta função é retornar o primeiro valor não nulo da lista de entradas (parâmetros) que estão sendo passados ​​para ela – o parâmetro também pode ser uma coluna.

Uma das abordagens para esses cenários é usar uma estrutura de armazenamento (tabela), que contém várias colunas. Apenas uma dessas colunas precisa ser preenchida para gerar informações significativas.

Passemos agora aos usos práticos.

Cenário de assinaturas de hospedagem na Web


Aqui, consideramos um provedor de serviços de hospedagem na web cujos serviços (pagos) são usados ​​por alguns clientes. Os clientes podem optar por pagar mensalmente, trimestralmente ou anualmente – de qualquer uma dessas maneiras.

Agora, supomos que os clientes acabaram de pagar no início de outubro. Assim, visualizamos uma estrutura tabular do ponto de vista do banco de dados da seguinte forma:

Construa uma tabela para armazenar pedidos


Precisamos construir uma tabela para armazenar todos os pedidos feitos pelos clientes por meio de qualquer uma das opções de pagamento disponíveis no banco de dados de amostra:
Use CoalesceUseDB

-- Create WebOrder table
CREATE TABLE [dbo].[WebOrder]
(
	[Id] INT NOT NULL, 
	[Customer] VARCHAR(40) NOT NULL, 
    [YearlyPayment] DECIMAL(10,2) NULL, 
    [QuarterlyPayment] DECIMAL(10,2) NULL, 
    [MonthlyPayment] DECIMAL(10,2) NULL, 
    [OrderDate] DATETIME2 NOT NULL, 
    CONSTRAINT [PK_WebOrder] PRIMARY KEY (Id) 
)

Preencha a tabela da seguinte forma:
-- Populate WebOrder table
INSERT INTO [dbo].[WebOrder] ([Id], [Customer], [YearlyPayment], [QuarterlyPayment], [MonthlyPayment], [OrderDate]) VALUES (1, N'Asif', CAST(70.00 AS Decimal(10, 2)), NULL, NULL, N'2020-10-01 00:00:00')
INSERT INTO [dbo].[WebOrder] ([Id], [Customer], [YearlyPayment], [QuarterlyPayment], [MonthlyPayment], [OrderDate]) VALUES (2, N'Peter', NULL, CAST(35.00 AS Decimal(10, 2)), NULL, N'2020-10-01 00:00:00')
INSERT INTO [dbo].[WebOrder] ([Id], [Customer], [YearlyPayment], [QuarterlyPayment], [MonthlyPayment], [OrderDate]) VALUES (3, N'Sarah', NULL, NULL, CAST(6.00 AS Decimal(10, 2)), N'2020-10-01 00:00:00')

Verificação rápida


Dê uma olhada rápida na tabela executando o seguinte script T-SQL:
-- View WebOrder table
SELECT wo.Id,wo.Customer,wo.YearlyPayment,wo.QuarterlyPayment,wo.MonthlyPayment,wo.OrderDate 
FROM dbo.WebOrder wo

A saída é:

Identifique o problema


Tudo parece bom, mas há um problema.

Queremos ver todos os pagamentos dos clientes, independentemente de terem feito um pagamento mensal, anual ou trimestral. Não parece haver uma maneira de juntar todos esses pagamentos evitando NULLs, especialmente se você trabalha em um relatório contendo todos os pedidos dos clientes e ignora se eles pagaram mensalmente, anualmente ou trimestralmente.

Projete a solução


A solução é usar a função COALESCE. Ele unirá todos esses modos de pagamento e excluirá valores NULL não essenciais.

Isso pode ser facilmente alcançado da seguinte forma:
--View all the web orders regardless of the payment mode
SELECT wo.Id,wo.Customer,COALESCE(wo.YearlyPayment,wo.QuarterlyPayment,wo.MonthlyPayment) AS Payment,wo.OrderDate 
FROM dbo.WebOrder wo

A saída é:

Usando o SQL View para melhorar a solução


Podemos melhorar essa solução transformando o script em uma visualização SQL e reutilizando-o para análise e relatórios:
-- Create AllWebOrders view
CREATE VIEW 
AllWebOrders
AS
SELECT wo.Id,wo.Customer,COALESCE(wo.YearlyPayment,wo.QuarterlyPayment,wo.MonthlyPayment) AS Payment,FORMAT(wo.OrderDate,'dd-MMM-yyyy') AS OrderDate
FROM dbo.WebOrder wo

Execute a visualização da seguinte forma:
--Run SQL View to see all the web orders
SELECT awo.Id,awo.Customer,awo.Payment,awo.OrderDate
FROM dbo.AllWebOrders awo

Os resultados são:

Dica:você pode criar um relatório do SSRS usando a visualização SQL como uma estratégia de recuperação de dados subjacente.

Cenário de organizações auto-referenciadas


Este é um cenário relacionado ao banco de dados de vida mais complicado, mas mais comum.

A maneira mais simples de entender isso é apelando para o relacionamento hierárquico (pai-filho). Aqui, consideramos uma tabela com todos os registros de funcionários e de seus gerentes. Essa tabela também armazena cada gerente como funcionário na mesma mesa.

No entanto, não vamos nos concentrar inteiramente na relação tabular funcionário-gerente aqui.

Vamos considerar uma hierarquia pai-filho em que cada organização pertence a uma principal. A própria organização principal é armazenada como uma organização na mesma estrutura para criar um relacionamento de autorreferência.

A melhor maneira de entender isso é construir a estrutura e ver você mesmo.

Construa uma tabela para armazenar o mestre e as suborganizações


Crie e preencha uma tabela SQL no banco de dados de amostra para armazenar o mestre e suas suborganizações da seguinte forma:
-- Creating master sub organisation table (self-referencing table)
CREATE TABLE [dbo].[Organisation]
(
	[Id] INT NOT NULL , 
    [Name] VARCHAR(40) NULL, 
	[Articles] INT NULL,
    [MasterId] INT NULL, 
    CONSTRAINT [PK_Organisation] PRIMARY KEY ([Id])
);
GO

-- Inserting data into the Organisation table
-- Populate Organisation table
INSERT INTO [dbo].[Organisation] ([Id], [Name], [Articles], [MasterId]) VALUES (1,'CodingSight',10, NULL)
INSERT INTO [dbo].[Organisation] ([Id], [Name], [Articles],[MasterId]) VALUES (2, 'SQL Blog', 2,1)
INSERT INTO [dbo].[Organisation] ([Id], [Name], [Articles],[MasterId]) VALUES (3, 'SSRS Blog', 3,1)
INSERT INTO [dbo].[Organisation] ([Id], [Name], [Articles],[MasterId]) VALUES (4,'CodingSight 2',5, NULL)
INSERT INTO [dbo].[Organisation] ([Id], [Name], [Articles],[MasterId]) VALUES (5, 'SSAS Blog', 1,4)
INSERT INTO [dbo].[Organisation] ([Id], [Name], [Articles],[MasterId]) VALUES (6,'SSIS Blog', 2,4)

Verificação rápida e análise


Podemos visualizar a tabela recém-criada executando a seguinte consulta:
-- View Organisation table
SELECT o.Id,o.Name,o.MasterId
FROM dbo.Organisation o

Então, obtemos o seguinte resultado:

Assim, podemos inferir que as seguintes organizações mestras estão armazenadas na tabela:
  1. CodingSight
  2. CodingSight 2

Se você observar a coluna MasterId, poderá ver que as organizações mestras têm NULL MasterId. É porque eles são organizações mestras.

As seguintes organizações estão sob a organização mestre CodingSight. Eles têm o MasterId apontando para o CodingSight organização:
  1. Blog SQL
  2. Blog SSRS

O mesmo vale para as seguintes suborganizações em CodingSight 2 Organização mestre:
  1. Blog SSAS
  2. Blog SSIS

Declaração do problema


Suponha que precisamos desenvolver um relatório de todos os artigos publicados por essas organizações, incluindo suas suborganizações, mas representadas pela organização principal.

Em palavras simples, precisamos construir um relatório para mostrar todos os artigos publicados por uma organização mestre, incluindo os artigos publicados por suas suborganizações, mas não podemos mencionar as suborganizações.

Projete a solução


A função COALESCE pode ser muito útil aqui, pois temos que encontrar NULLs para a organização mestre, mas colocar mestre e suborganização na função não ajudará.

Por exemplo, tentamos resumir artigos envolvendo seus ids na função da seguinte forma:
-- Getting total articles for each of the master and sub-organization without using COALESCE
SELECT O.Id,O.MasterId,SUM(O.Articles) as Total_Articles FROM dbo.Organisation O
GROUP BY O.MasterId,O.Id

A saída é:

Agora, vamos melhorar a saída usando a função desejada da seguinte forma:
-- Getting total articles for each of the master and sub organizations using COALESCE
SELECT COALESCE(O.Id,O.MasterId) MasterOrSubId,O.Name,SUM(O.Articles) as Total_Articles FROM dbo.Organisation O
GROUP BY COALESCE(O.Id,O.MasterId),O.Name

A saída é:

Combinamos com sucesso os IDs mestre e de suborganização para obter o número total de artigos publicados por essas organizações.

O script deve ser mais complicado para obter os resultados desejados, pois precisamos filtrar as suborganizações sem perder a contagem de seus artigos. Essa contagem deve ser atribuída às suas organizações principais.

Escreva o seguinte script T-SQL para conseguir isso:
-- Sum of all the articles published by the master organizations and their sub-organizations represented by the master organizations 
SELECT a.OrgId,o2.Name,a.Total_Articles FROM 
(SELECT COALESCE(O.MasterId,O.Id) AS OrgId,SUM(Articles) as Total_Articles FROM dbo.Organisation o
WHERE COALESCE(O.MasterId,O.Id) IN
(SELECT Id FROM dbo.Organisation where MasterId IS NULL)
GROUP BY COALESCE(O.MasterId,O.Id)) as a
INNER JOIN dbo.Organisation o2
on o2.Id=a.OrgId

A saída é:

Parabéns! Aprendemos com sucesso o uso prático da função COALESCE em alguns cenários interessantes em tempo real.

Coisas para fazer


Agora que você pode manipular valores NULL de forma eficaz e resolver problemas complexos com valores NULL, você precisa ser substituído de acordo com os requisitos de negócios. Vamos tentar as seguintes coisas para melhorar ainda mais suas habilidades:
  1. Tente criar e executar uma visualização SQL para o cenário de organização auto-referenciada:
  2. Consulte o Desenvolvimento de relatórios do SSRS em termos simples artigo e crie um relatório para o cenário de hospedagem na web.
  3. Adicione mais dados ao WebOrder tabela fornecendo diferentes OrderDate valores mencionados no cenário de serviços de hospedagem na web. Em seguida, transforme a visualização SQL em um procedimento armazenado que aceita a OrderDate parâmetro.
  4. Consulte o Criação de relatório SSRS profissional com base no procedimento armazenado artigo e crie um relatório com base na data do pedido para o cenário modificado discutido no ponto anterior.

Leia também


Principais respostas para 5 perguntas importantes sobre a função SQL COALESCE

Manipulando os valores NULL efetivamente com a função SQL COALESCE para iniciantes