sql >> Databáze >  >> RDS >> Mysql

Kontingenční tabulky v MySQL

  1. Stručně o kontingenčních tabulkách
  2. Pivoting dat pomocí nástrojů (dbForge Studio for MySQL)
  3. Pivoting dat pomocí SQL
    • Příklad pro SQL Server založený na T-SQL
    • Příklad pro MySQL
  4. Automatizace otáčení dat, dynamické vytváření dotazů

Stručně o kontingenčních tabulkách

Tento článek se zabývá transformací dat tabulky z řádků na sloupce. Taková transformace se nazývá kontingenční tabulky. Výsledkem pivotování je často souhrnná tabulka, ve které jsou statistické údaje prezentovány ve formě vhodné nebo požadované pro zprávu.
Kromě toho může být taková transformace dat užitečná, pokud databáze není normalizována a informace jsou v ní uloženy v neoptimální formě. Takže při reorganizaci databáze a přenosu dat do nových tabulek nebo při generování požadované reprezentace dat může být užitečné datové pivotování, tedy přesun hodnot z řádků do výsledných sloupců.
Níže je uveden příklad staré tabulky produktů – ProductsOld a nové – ProductsNew. Tohoto výsledku lze snadno dosáhnout pomocí transformace z řádků na sloupce.

Zde je příklad kontingenční tabulky.

Pivoting dat pomocí nástrojů (dbForge Studio for MySQL)

Existují aplikace, které mají nástroje umožňující implementovat pivotování dat ve vhodném grafickém prostředí. Například dbForge Studio pro MySQL obsahuje funkci kontingenčních tabulek, která poskytuje požadovaný výsledek v několika krocích.

Podívejme se na příklad se zjednodušenou tabulkou objednávek – PurchaseOrderHeader .

VYTVOŘIT TABULKU PurchaseOrderHeader ( PurchaseOrderID INT(11) NOT NULL, EmployeeID INT(11) NOT NULL, VendorID INT(11) NOT NULL, PRIMÁR KEY (PurchaseOrderID));INSERT PurchaseOrderHeader(Purchase1ErderID)VALUE , 258, 1580);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (2, 254, 1496);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (3, 254, 1496 Vendorch); ) VALUES (4, 261, 1650);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (5, 251, 1654);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID,3HederID15O VALUES(64INSERT) VALUESO64INSERT25 VALUES , ID zaměstnance, ID dodavatele) VALUES (7, 255, 1678);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (8, 256, 1616);INSERT PurchaseOrderHeader(PurchaseOrderID,929 Employee)14ID,259 Employee14ID INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (10, 250, 1602);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (11, 258, 1540);...

Předpokládejme, že potřebujeme provést výběr z tabulky a určit počet objednávek provedených určitými zaměstnanci od konkrétních dodavatelů. Seznam zaměstnanců, pro které jsou potřebné informace – 250, 251, 252, 253, 254.

Preferované zobrazení zprávy je následující.

Levý sloupec VendorID zobrazuje ID prodejců; sloupce Emp250 , Emp251 , Emp252 , Emp253 a Emp254 zobrazit počet objednávek.

Abyste toho dosáhli v dbForge Studio pro MySQL, musíte:

  • Přidejte tabulku jako zdroj dat pro reprezentaci dokumentu „Kontingenční tabulka“. V Průzkumníku databáze klikněte pravým tlačítkem na PurchaseOrderHeader tabulky a vyberte možnost Odeslat do a poté Kontingenční tabulka ve vyskakovací nabídce.
  • Určete sloupec, jehož hodnoty budou řádky. Přetáhněte ID dodavatele do pole „Sem přetáhněte pole řádků“.
  • Určete sloupec, jehož hodnoty budou sloupce. Přetáhněte EmployeeID do pole „Sem přetáhněte pole sloupců“. Můžete také nastavit filtr pro požadované zaměstnance (250, 251, 252, 253, 254).
  • Určete sloupec, jehož hodnoty budou data. Přetáhněte PurchaseOrderID do pole ‚Dat Data Items Here‘.
  • Ve vlastnostech PurchaseOrderID zadejte typ agregace – Počet hodnot .

Rychle jsme získali výsledek, který potřebujeme.

Pivoting dat pomocí SQL

Transformaci dat lze samozřejmě provádět pomocí databáze napsáním SQL dotazu. Je tu ale malý háček, MySQL nemá konkrétní příkaz, který by to umožňoval.

Příklad pro SQL Server založený na T-SQL

Například SqlServer a Oracle mají operátor PIVOT, který umožňuje takovou transformaci dat. Pokud bychom pracovali se SqlServerem, náš dotaz by vypadal takto.

SELECT VendorID ,[250] AS Emp1 ,[251] AS Emp2 ,[252] AS Emp3 ,[253] AS Emp4 ,[254] AS Emp5FROM (SELECT PurchaseOrderID ,EmployeeID ,VendorID FROM Purchasing.PIPVOTPurchasing.PipVOT (ID nákupu) PRO ID zaměstnance V ([250], [251], [252], [253], [254])) JAKO OBJEDNÁVKA OD t.VendorID;

Příklad pro MySQL

V MySQL budeme muset použít prostředky SQL. Data by měla být seskupena podle sloupce dodavatele – VendorID a pro každého požadovaného zaměstnance (EmployeeID ), musíte vytvořit samostatný sloupec s agregační funkcí.

V našem případě potřebujeme spočítat počet objednávek, proto použijeme agregační funkci POČET.

Ve zdrojové tabulce jsou informace o všech zaměstnancích uloženy v jednom sloupci EmployeeID a potřebujeme vypočítat počet objednávek pro konkrétního zaměstnance, takže musíme naši agregační funkci naučit zpracovávat pouze určité řádky.

Agregační funkce nebere v úvahu hodnoty NULL a tuto zvláštnost využíváme pro naše účely.

Můžete použít podmíněný operátor IF nebo CASE, který vrátí konkrétní hodnotu pro požadovaného zaměstnance, jinak jednoduše vrátí NULL; v důsledku toho bude funkce COUNT počítat pouze hodnoty jiné než NULL.

Výsledný dotaz je následující:

VYBERTE ID dodavatele, POČET(POKUD(IDZaměstnance =250, IDObjednávky nákupu, NULL)) JAKO Emp250, POČET (POKUD (ID zaměstnance =251, ID objednávky, NULL)) JAKO Emp251, POČET (POKUD (ID zaměstnance, ID nákupu =25NULLOrder25) ) AS Emp252, COUNT(IF(EmployeeID =253, PurchaseOrderID, NULL)) AS Emp253, COUNT(IF(IF(EmployeeID =254, PurchaseOrderID, NULL)) AS Emp254FROM PurchaseOrderHeader pWHEET20 AND2eID5GROUP p.Em> 

Nebo dokonce takto:

ID dodavatele, COUNT(IF(ID zaměstnance =250, 1, NULL)) JAKO Emp250, COUNT(IF(ID zaměstnance =251, 1, NULL)) JAKO Emp251, COUNT(IF(ID zaměstnance =252, NULL) 1, 1, JAKO Emp252, COUNT(IF(ID zaměstnance =253, 1, NULL)) JAKO Emp253, COUNT(IF(ID zaměstnance =254, 1, NULL)) AS Emp254FROM PurchaseOrderHeader pWHERE p.EmployeeID250ID BET; 

Po provedení se získá známý výsledek.

Automatizace pivotování dat, dynamické vytváření dotazů

Jak je vidět, dotaz má určitou konzistenci, tedy všechny transformované sloupce jsou tvořeny podobným způsobem a pro sepsání dotazu potřebujete znát konkrétní hodnoty z tabulky. Chcete-li vytvořit pivotní dotaz, musíte zkontrolovat všechny možné hodnoty a teprve poté byste měli napsat dotaz. Alternativně můžete tuto úlohu předat serveru, aby získal tyto hodnoty a dynamicky provedl rutinní úlohu.

Vraťme se k prvnímu příkladu, ve kterém jsme vytvořili novou tabulku ProductsNew ze ProduktyStaré stůl. Tam jsou hodnoty vlastností omezené a my ani nemůžeme znát všechny možné hodnoty; máme pouze informaci o tom, kde jsou uloženy názvy vlastností a jejich hodnota. Toto jsou Vlastnosti a Hodnota sloupců.

Celý algoritmus tvorby SQL dotazu spočívá v získání hodnot, ze kterých se budou tvořit nové sloupce a zřetězení neměnných částí dotazu.

SELECT GROUP_CONCAT( CONCAT( ' MAX(IF(Vlastnost =''', t.Vlastnost, ''', Hodnota, NULL)) AS ', t.Property ) ) INTO @PivotQueryFROM (SELECT Property FROM ProductOld GROUP BY Vlastnost) t;SET @PivotQuery =CONCAT('SELECT ProductID,', @PivotQuery, ' FROM ProductOld GROUP BY ProductID');

Proměnná @PivotQuery uloží náš dotaz, text byl kvůli přehlednosti naformátován.

SELECT ProductID, MAX(IF(Vlastnost ='Barva', Hodnota, NULL)) AS Barva, MAX(IF(Vlastnost ='Název', Hodnota, NULL)) AS Název, MAX(IF(Vlastnost ='Číslo produktu) ', Value, NULL)) AS ProductNumber, MAX(IF(Property ='Size', Value, NULL)) AS Size, MAX(IF(Property ='SizeUnitMeasureCode', Value, NULL)) AS SizeUnitMeasureCodeFROM ProductOldGROUP BY ProductID 

Po jeho provedení získáme požadovaný výsledek odpovídající schématu tabulky ProductsNew.
Dotaz z proměnné @PivotQuery lze navíc provést ve skriptu pomocí příkazu MySQL EXECUTE.

Příkaz PREPARE FROM @PivotQuery;příkaz EXECUTE;příkaz DEALLOCATE PREPARE;

  1. MIN/MAX vs. ORDER BY a LIMIT

  2. Jak filtrovat řádky bez NULL ve sloupci

  3. Jak funguje funkce TRIM() v MySQL

  4. Jak na serveru SQL Server pivotovat pro více sloupců