Database
 sql >> база данни >  >> RDS >> Database

Практическа употреба на функцията SQL COALESCE

Тази статия говори за практическото използване на функцията SQL COALESCE по отношение на някои професионални житейски сценарии. Той подчертава важността на правилното и навременно използване на тази функция за справяне с проблемите, свързани с базата данни.

Освен това ще приложим конкретните стъпки, необходими за решаване на проблемите с помощта на тази функция.

Предварителни условия

Преди да се подготвите да прегледате и приложите предстоящите примери в тази статия, силно се препоръчва да се запознаете със следните проблеми:

  • Основи на T-SQL . Читателите трябва да са добре запознати с T-SQL скриптовете. Освен това те трябва удобно да пишат и изпълняват SQL заявки към примерни бази данни.
  • Основи на функцията COALESCE . Читателите трябва да са запознати с тази област. Ако имате нужда от информацията, за да я изучите, вижте статията Ефективна обработка на NULL стойности на SQL COALESCE .

Примерна база данни

Настройте примерна база данни, наречена CoalesceUseDB както следва:

-- Setup sample database
Create DATABASE CoalesceUseDB;
GO

Като алтернатива можете да изпълнявате заявки срещу tempdb база данни, ако предпочитате да го направите.

Мисли относно практическата употреба

Ще разгледаме два практически случая на използване на функцията COALESCE. Трябва да имаме предвид, че главната цел на тази функция е да върне първата стойност без нула от списъка с входове (параметри), които се предават към нея – параметърът може да бъде и колона.

Един от подходите към подобни сценарии е използването на структура за съхранение (таблица), която съдържа множество колони. Само една от тези колони трябва да бъде попълнена, за да има смислена информация.

Нека сега да преминем през практическите приложения.

Сценарий за абонаменти за уеб хостинг

Тук ние разглеждаме доставчик на уеб хостинг услуги, чиито (платени) услуги се използват от някои клиенти. Клиентите могат да избират да плащат месечно, тримесечно или годишно – по всеки от тези начини.

Сега предполагаме, че клиентите току-що са платили в началото на октомври. По този начин ние визуализираме таблична структура от гледна точка на базата данни, както следва:

Създайте таблица за съхранение на поръчки

Трябва да изградим таблица, която да съхранява всички поръчки, направени от клиентите чрез някоя от наличните опции за плащане, спрямо примерната база данни:

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

Попълнете таблицата, както следва:

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

Бърза проверка

Разгледайте бързо таблицата, като изпълните следния T-SQL скрипт:

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

Резултатът е:

Определете проблема

Всичко изглежда добре, но има проблем.

Искаме да разгледаме всички плащания на клиентите, независимо дали са направили месечно, годишно или тримесечно плащане. Изглежда няма начин да обедините всички тези плащания заедно, като избягвате NULL, особено ако работите върху отчет, съдържащ всички поръчки на клиенти, и игнорирате дали са плащали месечно, годишно или тримесечно.

Проектирайте решението

Решението е да използвате функцията COALESCE. Той ще обедини всички тези режими на плащане заедно и ще изключи несъществени NULL стойности.

Това може лесно да се постигне по следния начин:

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

Резултатът е:

Използване на SQL изглед за подобряване на решението

Можем да подобрим това решение, като превърнем скрипта в SQL изглед и го използваме повторно за анализ и отчитане:

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

Стартирайте изгледа, както следва:

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

Резултатите са:

Съвет:можете да създадете SSRS отчет, като използвате SQL изгледа като основна стратегия за извличане на данни.

Сценарий на организации за саморефериране

Това е по-сложен, но по-често срещан сценарий, свързан с базата данни за живота.

Най-простият начин да го разберете е да се обърнете към йерархичната връзка (родител-дете). Тук разглеждаме таблица с записи на всички служители и записи на техните мениджъри. Тази таблица също така съхранява всеки мениджър като служител на същата маса.

Тук обаче няма да се фокусираме изцяло върху табличната връзка между служители и мениджъри.

Нека разгледаме йерархията родител-дете, където всяка организация принадлежи на главна. Самата главна организация се съхранява като организация в същата структура, за да се създаде връзка за саморефериране.

Най-добрият начин да разберете това е да изградите структурата и да я видите сами.

Създайте таблица за съхранение на главни и подорганизации

Създайте и попълнете SQL таблица в примерната база данни, за да съхранявате главния и неговите подорганизации, както следва:

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

Бърза проверка и анализ

Можем да видим новосъздадената таблица, като изпълним следната заявка:

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

След това получаваме следния резултат:

По този начин можем да заключим, че следните главни организации се съхраняват в таблицата:

  1. CodingSight
  2. CodingSight 2

Ако погледнете колоната MasterId, можете да видите, че главните организации имат NULL MasterId. Това е така, защото те са главни организации.

Следните организации са под главната организация на CodingSight. Те имат MasterId, сочещи към CodingSight организация:

  1. Блог за SQL
  2. Блог за SSRS

Същото важи и за следните подорганизации под CodingSight 2 Главна организация:

  1. Блог на SSAS
  2. Блог за SSIS

Постановка на проблема

Да предположим, че трябва да разработим отчет за всички статии, публикувани от тези организации, включително техните подорганизации, но представени от главната организация.

С прости думи, трябва да изградим отчет, който да показва всички статии, публикувани от основна организация, включително тези статии, публикувани от нейните подорганизации, но не можем да споменем подорганизациите.

Проектирайте решението

Функцията COALESCE може да бъде много удобна тук, тъй като трябва да срещнем NULL за главната организация, но поставянето на главна и подорганизация във функцията няма да помогне.

Например, ние се опитваме да обобщим статиите, като обвиваме техните идентификатори във функцията, както следва:

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

Резултатът е:

Сега нека подобрим изхода, като използваме желаната функция, както следва:

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

Резултатът е:

Успешно обединихме идентификатори на главни и подорганизации, за да получим общия брой статии, публикувани от тези организации.

Скриптът трябва да бъде по-сложен, за да получим желаните резултати, тъй като трябва да филтрираме подорганизациите, без да губим броя на техните статии. Този брой трябва да бъде присвоен на техните главни организации.

Напишете следния T-SQL скрипт, за да постигнете това:

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

Резултатът е:

Честито! Успешно научихме практическото използване на функцията COALESCE по отношение на някои интересни сценарии в реално време.

Неща за правене

Сега, когато можете ефективно да обработвате стойности NULL и да решавате сложни проблеми с NULL стойности, трябва да бъдете заместени според бизнес изискванията. Нека опитаме следните неща, за да подобрим допълнително уменията си:

  1. Опитайте се да създадете и стартирате SQL изглед за сценария на самореферентна организация:
  2. Вижте Разработване на SSRS отчети с прости думи статия и създайте отчет за сценария на уеб хостинг.
  3. Добавете още данни към WebOrder таблица чрез предоставяне на различна OrderDate стойности, споменати в сценария на уеб хостинг услуги. След това превърнете SQL изгледа в съхранена процедура, която приема OrderDate параметър.
  4. Вижте Създаване на професионален SSRS отчет въз основа на съхранена процедура статия и съставете отчет въз основа на датата на поръчката за модифицирания сценарий, обсъден в предишната точка.

Прочетете също

Най-добри отговори на 5 горящи въпроса за функцията SQL COALESCE

Ефективна обработка на стойностите NULL с функцията SQL COALESCE за начинаещи


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. StarJoinInfo в планове за изпълнение

  2. Как да получите годината от дата в T-SQL

  3. Пазете се от подвеждащи данни от SET STATISTICS IO

  4. Десет често срещани заплахи за качеството на плана за изпълнение

  5. Как да зареждате и управлявате данни в Microsoft Power BI