sql >> Databasteknik >  >> RDS >> Database

En praktisk användning av SQL COALESCE-funktionen

Den här artikeln talar om den praktiska användningen av SQL COALESCE-funktionen när det gäller vissa scenarier i yrkeslivet. Den understryker vikten av att den här funktionen används korrekt och i tid för att lösa de databasrelaterade problemen.

Dessutom kommer vi att implementera de särskilda steg som krävs för att lösa problemen med hjälp av den här funktionen.

Förutsättningar

Innan du förbereder dig för att granska och implementera de kommande exemplen i den här artikeln, rekommenderas det starkt att du bekantar dig med följande problem:

  • Grundläggande om T-SQL . Läsare bör vara väl medvetna om T-SQL-skript. De behöver också skriva och köra SQL-frågor mot exempeldatabaser bekvämt.
  • Grunderna för COALESCE-funktionen . Läsare måste vara bekanta med detta område. Om du behöver informationen för att studera den, se artikeln SQL COALESCE-funktioner hanterar NULL-värden effektivt .

Exempeldatabas

Konfigurera en exempeldatabas som heter CoalesceUseDB enligt följande:

-- Setup sample database
Create DATABASE CoalesceUseDB;
GO

Alternativt kan du köra frågor mot tempdb databas om du föredrar att göra det.

Tänker om praktisk användning

Vi kommer att granska två praktiska användningsfall av COALESCE-funktionen. Vi bör komma ihåg att huvudmålet med den här funktionen är att returnera det första Non-Null-värdet från listan över indata (parametrar) som skickas till den – aparameter kan också vara en kolumn.

En av metoderna för sådana scenarier är att använda en lagringsstruktur (tabell), som innehåller flera kolumner. Endast en av dessa kolumner behöver fyllas i för att ge meningsfull information.

Låt oss nu gå igenom de praktiska användningarna.

Scenario för webbhotellprenumerationer

Här överväger vi en webbhotellleverantör vars (betalda) tjänster används av vissa kunder. Kunder kan välja att betala månadsvis, kvartalsvis eller årligen – på något av dessa sätt.

Nu antar vi att kunderna precis har betalat i början av oktober. Sålunda visualiserar vi en tabellstruktur från databassynpunkt enligt följande:

Skapa en tabell för att lagra beställningar

Vi måste bygga en tabell för att lagra alla beställningar gjorda av kunderna via något av de tillgängliga betalningsalternativen mot exempeldatabasen:

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) 
)

Fyll i tabellen enligt följande:

-- 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')

Snabbkontroll

Ta en snabb titt på tabellen genom att köra följande T-SQL-skript:

-- View WebOrder table
SELECT wo.Id,wo.Customer,wo.YearlyPayment,wo.QuarterlyPayment,wo.MonthlyPayment,wo.OrderDate 
FROM dbo.WebOrder wo

Utdata är:

Identifiera problemet

Allt ser bra ut, men det finns ett problem.

Vi vill titta på alla kunders betalningar, oavsett om de gjort en månads-, års- eller kvartalsbetalning. Det verkar inte finnas något sätt att sammanfoga alla dessa betalningar genom att undvika NULL, särskilt om du arbetar med en rapport som innehåller alla kunders beställningar och ignorerar om de betalade månadsvis, årligen eller kvartalsvis.

Designa lösningen

Lösningen är att använda COALESCE-funktionen. Det kommer att slå samman alla dessa betalningssätt och exkludera icke-väsentliga NULL-värden.

Detta kan enkelt uppnås enligt följande:

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

Utdata är:

Använda SQL View för att förbättra lösningen

Vi kan förbättra den här lösningen genom att omvandla skriptet till en SQL-vy och återanvända det för analys och rapportering:

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

Kör vyn enligt följande:

--Run SQL View to see all the web orders
SELECT awo.Id,awo.Customer,awo.Payment,awo.OrderDate
FROM dbo.AllWebOrders awo

Resultaten är:

Tips:du kan skapa en SSRS-rapport med SQL-vyn som en underliggande strategi för datahämtning.

Senario för självrefererande organisationer

Detta är ett mer komplicerat men vanligare livsdatabasrelaterat scenario.

Det enklaste sättet att förstå det är att tilltala den hierarkiska (förälder-barn) relationen. Här ser vi en tabell med alla anställdas register och deras chefers register. Denna tabell lagrar också varje chef som anställd vid samma bord.

Vi kommer dock inte att fokusera helt på anställd-chefens tabellförhållande här.

Låt oss överväga en förälder-barn-hierarki där varje organisation tillhör en master. Själva huvudorganisationen lagras som en organisation i samma struktur för att skapa en självrefererande relation.

Det bästa sättet att förstå detta är att bygga strukturen och se den själv.

Skapa ett bord för att lagra huvud- och underorganisationer

Skapa och fyll i en SQL-tabell i exempeldatabasen för att lagra mastern och dess underorganisationer enligt följande:

-- 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)

Snabbkontroll och analys

Vi kan se den nyskapade tabellen genom att köra följande fråga:

-- View Organisation table
SELECT o.Id,o.Name,o.MasterId
FROM dbo.Organisation o

Sedan får vi följande resultat:

Således kan vi dra slutsatsen att följande huvudorganisationer är lagrade i tabellen:

  1. CodingSight
  2. CodingSight 2

Om du tittar på kolumnen MasterId kan du se att masterorganisationerna har NULL MasterId. Det är för att de är mästarorganisationer.

Följande organisationer är under CodingSights huvudorganisation. De har MasterId som pekar på CodingSight organisation:

  1. SQL-blogg
  2. SSRS-blogg

Detsamma gäller för följande underorganisationer under CodingSight 2 Huvudorganisation:

  1. SSAS-blogg
  2. SSIS-blogg

Problembeskrivning

Anta att vi behöver utveckla en rapport över alla artiklar som publicerats av dessa organisationer, inklusive deras underorganisationer, men representerade av huvudorganisationen.

Med enkla ord måste vi skapa en rapport för att visa alla artiklar som publicerats av en huvudorganisation, inklusive de artiklar som publicerats av dess underorganisationer, men vi kan inte nämna underorganisationerna.

Designa lösningen

COALESCE-funktionen kan vara väldigt praktisk här eftersom vi måste stöta på NULLs för huvudorganisationen, men det hjälper inte att lägga in master och underorganisation i funktionen.

Till exempel försöker vi summera artiklar genom att slå in deras ID i funktionen enligt följande:

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

Utdata är:

Låt oss nu förbättra resultatet genom att använda önskad funktion enligt följande:

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

Utdata är:

Vi har framgångsrikt slagit samman huvud- och underorganisations-ID för att få det totala antalet artiklar publicerade av dessa organisationer.

Skriptet måste vara mer komplicerat för att få önskat resultat eftersom vi behöver filtrera bort underorganisationer utan att tappa antalet artiklar. Den räkningen bör tilldelas deras huvudorganisationer.

Skriv följande T-SQL-skript för att uppnå detta:

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

Utdata är:

Grattis! Vi har framgångsrikt lärt oss den praktiska användningen av COALESCE-funktionen för några intressanta realtidsscenarier.

Saker att göra

Nu när du kan hantera NULL-värden effektivt och lösa komplexa problem med NULL-värden, måste du ersättas enligt affärskrav. Låt oss prova följande saker för att förbättra dina färdigheter ytterligare:

  1. Försök att skapa och köra en SQL-vy för scenariot med självreferensorganisation:
  2. Se SSRS-rapportutveckling i enkla termer artikel och skapa en rapport för webbhotellscenariot.
  3. Lägg till mer data i WebOrder tabell genom att ange olika OrderDate värden som nämns i scenariot för webbhotelltjänster. Förvandla sedan SQL-vyn till en lagrad procedur som accepterar OrderDate parameter.
  4. Se Skapa professionell SSRS-rapport baserat på lagrad procedur artikel och skapa en beställningsdatumbaserad rapport för det modifierade scenariot som diskuterades i föregående punkt.

Läs också

De bästa svaren på 5 brännande frågor om SQL COALESCE-funktion

Hantera NULL-värdena effektivt med SQL COALESCE-funktionen för nybörjare


  1. Migrera från MySQL till PostgreSQL - Vad du bör veta

  2. UnsatisfiedLinkError i ursprunglig metod

  3. hur man kontrollerar att databasen är konsekvent efter ofullständig återställning

  4. Reducerar parametern postgresql.conf, åt gången