Tento článek je o funkcích okna T-SQL (Transact-SQL) a jejich základním použití v každodenních úlohách analýzy dat.
Pokud jde o analýzu dat, existuje mnoho alternativ k T-SQL. Nicméně, když se zváží zlepšení v průběhu času a zavedení funkcí Window, T-SQL je schopen provádět analýzu dat na základní úrovni a v některých případech i mimo ni.
O funkcích okna SQL
Nejprve se nejprve seznámíme s funkcemi okna SQL v kontextu dokumentace společnosti Microsoft.
Definice společnosti Microsoft
Funkce okna vypočítá hodnotu pro každý řádek v okně.
Jednoduchá definice
Funkce okna nám pomáhá zaměřit se na určitou část (okno) sady výsledků, takže můžeme provádět analýzu dat pouze pro tuto konkrétní část (okno), nikoli pro celou sadu výsledků.
Jinými slovy, funkce okna SQL mění sadu výsledků na několik menších sad pro účely analýzy dat.
Co je sada výsledků
Jednoduše řečeno, sada výsledků se skládá ze všech záznamů získaných spuštěním SQL dotazu.
Můžeme například vytvořit tabulku s názvem Produkt a vložte do něj následující data:
-- (1) Create the Product table CREATE TABLE [dbo].[Product] ( [ProductId] INT NOT NULL PRIMARY KEY, [Name] VARCHAR(40) NOT NULL, [Region] VARCHAR(40) NOT NULL ) -- (2) Populate the Product table INSERT INTO Product (ProductId,Name,Region) VALUES (1,'Laptop','UK'),(2,'PC','UAE'),(3,'iPad','UK')
Nyní bude sada výsledků načtená pomocí níže uvedeného skriptu obsahovat všechny řádky z Produktu tabulka:
-- (3) Result set SELECT [ProductId], [Name],[Region] FROM Product
Co je to okno
Je důležité nejprve porozumět konceptu okna ve vztahu k funkcím okna SQL. V tomto kontextu je okno jen způsob, jak zúžit rozsah zacílením na konkrétní část sady výsledků (jak jsme již uvedli výše).
Možná se teď ptáte – co vlastně znamená „cílení na konkrétní část sady výsledků“?
Vrátíme-li se k příkladu, na který jsme se podívali, můžeme vytvořit okno SQL založené na oblasti produktu rozdělením sady výsledků do dvou oken.
Porozumění Row_Number()
Abychom mohli pokračovat, budeme muset použít funkci Row_Number() který dočasně přiřadí pořadové číslo výstupním řádkům.
Například, pokud chceme přidat čísla řádků do sady výsledků na základě ProductID, budeme muset použít ROW_NUMBER() objednat podle ID produktu následovně:
--Using the row_number() function to order the result set by ProductID SELECT ProductID,ROW_NUMBER() OVER (ORDER BY ProductID) AS SrNo,Name,Region FROM Product
Nyní, pokud chceme funkci Row_Number() k uspořádání sady výsledků podle ID produktu sestupně, pak posloupnost výstupních řádků na základě ProductID se změní následovně:
--Using the row_number() function to order the result set by ProductID descending SELECT ProductID,ROW_NUMBER() OVER (ORDER BY ProductID DESC) AS SrNo,Name,Region FROM Product
Zatím zde nejsou žádná okna SQL, protože jedinou věcí, kterou jsme udělali, je seřazení sady podle konkrétních kritérií. Jak již bylo zmíněno dříve, okno znamená rozdělit sadu výsledků na několik menších sad a analyzovat každou z nich samostatně.
Vytvoření okna pomocí Row_Number()
Abychom vytvořili okno SQL v naší výsledkové sadě, budeme jej muset rozdělit podle kteréhokoli ze sloupců, které obsahuje.
Nyní můžeme výslednou sadu rozdělit podle oblastí následovně:
--Creating a SQL window based on Region SELECT ROW_NUMBER() OVER (Partition by region ORDER BY Region) as Region_Serial_Number , Name, Region FROM dbo.Product
Vybrat – přes klauzuli
Jinými slovy, Vybrat s Konec klauzule připravuje cestu pro funkce okna SQL rozdělením sady výsledků na menší okna.
Podle dokumentace společnosti Microsoft Vybrat s Přes klauzule definuje okno, které pak může být použito jakoukoli funkcí okna.
Nyní vytvoříme tabulku s názvem KitchenProduct takto:
CREATE TABLE [dbo].[KitchenProduct] ( [KitchenProductId] INT NOT NULL PRIMARY KEY IDENTITY(1,1), [Name] VARCHAR(40) NOT NULL, [Country] VARCHAR(40) NOT NULL, [Quantity] INT NOT NULL, [Price] DECIMAL(10,2) NOT NULL ); GO INSERT INTO dbo.KitchenProduct (Name, Country, Quantity, Price) VALUES ('Kettle','Germany',10,15.00) ,('Kettle','UK',20,12.00) ,('Toaster', 'France',10,10.00) ,('Toaster','UAE',10,12.00) ,('Kitchen Clock','UK',50,20.00) ,('Kitchen Clock','UAE',35,15.00)
Nyní se podívejme na tabulku:
SELECT [KitchenProductId], [Name], [Country], [Quantity], [Price] FROM dbo.KitchenProduct
Pokud chcete vidět každý produkt s vlastním sériovým číslem, nikoli s číslem založeným na zobecněném ID produktu, pak byste museli použít funkci okna SQL k rozdělení výsledné sady podle produktu následovně:
-- Viewing each product in its own series SELECT ROW_NUMBER() OVER (Partition by Name order by Name) Product_SrNo,Name,Country,Quantity FROM dbo.KitchenProduct
Kompatibilita (výběr – přes klauzuli)
Podle dokumentace společnosti Microsoft , Select – Over Clause je kompatibilní s následujícími verzemi databáze SQL:
- SQL Server 2008 a novější
- Azure SQL Database
- Azure SQL Data Warehouse
- Paralelní datový sklad
Syntaxe
VYBRAT – PŘED (Rozdělení podle
Upozorňujeme, že jsem zjednodušil syntaxi na i t snadno pochopitelné; viz ten Dokumentace společnosti Microsoft k zobrazení plné syntaxe.
Předpoklady
Tento článek je v podstatě napsán pro začátečníky, ale stále existují určité předpoklady, které je třeba mít na paměti.
Znalost T-SQL
Tento článek předpokládá, že čtenáři mají základní znalosti T-SQL a jsou schopni psát a spouštět základní SQL skripty.
Nastavení ukázkové tabulky Prodej
Tento článek vyžaduje následující ukázkovou tabulku, abychom mohli spustit příklady funkcí okna SQL:
-- (1) Create the Sales sample table CREATE TABLE [dbo].[Sales] ( [SalesId] INT NOT NULL IDENTITY(1,1), [Product] VARCHAR(40) NOT NULL, [Date] DATETIME2, [Revenue] DECIMAL(10,2), CONSTRAINT [PK_Sales] PRIMARY KEY ([SalesId]) ); GO -- (2) Populating the Sales sample table SET IDENTITY_INSERT [dbo].[Sales] ON INSERT INTO [dbo].[Sales] ([SalesId], [Product], [Date], [Revenue]) VALUES (1, N'Laptop', N'2017-01-01 00:00:00', CAST(200.00 AS Decimal(10, 2))) INSERT INTO [dbo].[Sales] ([SalesId], [Product], [Date], [Revenue]) VALUES (2, N'PC', N'2017-01-01 00:00:00', CAST(100.00 AS Decimal(10, 2))) INSERT INTO [dbo].[Sales] ([SalesId], [Product], [Date], [Revenue]) VALUES (3, N'Mobile Phone', N'2018-01-01 00:00:00', CAST(300.00 AS Decimal(10, 2))) INSERT INTO [dbo].[Sales] ([SalesId], [Product], [Date], [Revenue]) VALUES (4, N'Accessories', N'2018-01-01 00:00:00', CAST(150.00 AS Decimal(10, 2))) INSERT INTO [dbo].[Sales] ([SalesId], [Product], [Date], [Revenue]) VALUES (5, N'iPad', N'2019-01-01 00:00:00', CAST(300.00 AS Decimal(10, 2))) INSERT INTO [dbo].[Sales] ([SalesId], [Product], [Date], [Revenue]) VALUES (6, N'PC', N'2019-01-01 00:00:00', CAST(200.00 AS Decimal(10, 2))) INSERT INTO [dbo].[Sales] ([SalesId], [Product], [Date], [Revenue]) VALUES (7, N'Laptop', N'2019-01-01 00:00:00', CAST(300.00 AS Decimal(10, 2))) SET IDENTITY_INSERT [dbo].[Sales] OFF
Zobrazte všechny prodeje spuštěním následujícího skriptu:
-- View sales SELECT [SalesId],[Product],[Date],[Revenue] FROM dbo.Sales
Seskupit podle vs SQL funkce okna
Člověk se může divit – jaký je rozdíl mezi použitím klauzule Seskupit podle a funkcí okna SQL?
Odpověď leží v příkladech níže.
Seskupit podle příkladu
Abychom viděli celkový prodej podle produktu, můžeme použít Seskupit takto:
-- Total sales by product using Group By SELECT Product ,SUM(REVENUE) AS Total_Sales FROM dbo.Sales GROUP BY Product ORDER BY Product
Klauzule Group By nám tedy pomáhá vidět celkové prodeje. Celková hodnota prodeje je součtem tržeb za všechny podobné produkty na stejném řádku bez použití klauzule Seskupit podle. Co když máme zájem vidět tržby (prodej) každého jednotlivého produktu spolu s celkovým prodejem?
Zde vstoupí do akce funkce okna SQL.
Příklad funkce okna SQL
Abychom viděli produkt, tržby a celkové tržby všech podobných produktů, musíme data rozdělit na základě vedlejších produktů pomocí OVER() takto:
-- Total sales by product using an SQL window function SELECT Product ,REVENUE ,SUM(REVENUE) OVER (PARTITION BY PRODUCT) AS Total_Sales FROM dbo.Sales
Výstup by měl být následující:
Nyní tedy můžeme snadno vidět tržby za každý jednotlivý produkt spolu s celkovým prodejem tohoto produktu. Například tržby za PC je 100,00, ale celkové tržby (součet příjmů za PC produkt) je 300,00, protože se prodávaly dva různé modely PC.
Základní analýza s agregačními funkcemi
Agregační funkce vrátí jednu hodnotu po provedení výpočtů na sadě dat.
V této části dále prozkoumáme funkce okna SQL – konkrétně je použijeme spolu s agregačními funkcemi k provedení základní analýzy dat.
Běžné agregační funkce
Nejběžnější agregační funkce jsou:
- Součet
- Počet
- Min
- Maximálně
- Průměr (průměr)
Analýza souhrnných dat podle produktu
Abychom mohli analyzovat sadu výsledků na základě vedlejších produktů pomocí agregačních funkcí, musíme jednoduše použít agregační funkci s oddílem vedlejšího produktu uvnitř příkazu OVER():
-- Data analysis by product using aggregate functions SELECT Product,Revenue ,SUM(REVENUE) OVER (PARTITION BY PRODUCT) as Total_Sales ,MIN(REVENUE) OVER (PARTITION BY PRODUCT) as Minimum_Sales ,MAX(REVENUE) OVER (PARTITION BY PRODUCT) as Maximum_Sales ,AVG(REVENUE) OVER (PARTITION BY PRODUCT) as Average_Sales FROM dbo.Sales
Pokud se podíváte blíže na PC nebo Laptop produkty, uvidíte, jak agregační funkce spolupracují spolu s funkcí okna SQL.
Ve výše uvedeném příkladu vidíme, že hodnota Tržby pro PC je 100,00 poprvé a 200,00 příště, ale celkový prodej činí 300,00. Podobné informace lze vidět pro zbytek agregačních funkcí.
Analýza souhrnných dat podle data
Nyní provedeme analýzu dat produktů podle jednotlivých dat pomocí okenních funkcí SQL v kombinaci s agregačními funkcemi.
Tentokrát rozdělíme sadu výsledků podle data, nikoli podle produktu následovně:
-- Data analysis by date using aggregate functions SELECT Product,date,Revenue ,SUM(REVENUE) OVER (PARTITION BY DATE) as Total_Sales ,MIN(REVENUE) OVER (PARTITION BY DATE) as Minimum_Sales ,MAX(REVENUE) OVER (PARTITION BY DATE) as Maximum_Sales ,AVG(REVENUE) OVER (PARTITION BY DATE) as Average_Sales FROM dbo.Sales
Díky tomu jsme se naučili základní techniky analýzy dat pomocí přístupu funkcí okna SQL.
Co dělat
Nyní, když jste obeznámeni s funkcemi okna SQL, zkuste následující:
- S ohledem na příklady, na které jsme se podívali, proveďte základní analýzu dat pomocí funkcí okna SQL ve vzorové databázi uvedené v tomto článku.
- Přidejte sloupec Zákazník do vzorové tabulky Prodej a uvidíte, jak bohatá může být vaše analýza dat, když do ní přidáte další sloupec (zákazník).
- Přidání sloupce Region do vzorové tabulky Prodej a provedení základní analýzy dat pomocí agregačních funkcí podle regionu.