- Kort om pivottabeller
- Pivotering av data med hjälp av verktyg (dbForge Studio för MySQL)
- Pivotering av data med hjälp av SQL
- T-SQL-baserat exempel för SQL Server
- Exempel för MySQL
- Automatisk datapivotering, skapa sökfråga dynamiskt
Kort om pivottabeller
Den här artikeln handlar om omvandlingen av tabelldata från rader till kolumner. Sådan transformation kallas pivottabeller. Ofta är resultatet av pivoten en sammanfattande tabell där statistiska data presenteras i den form som är lämplig eller krävs för en rapport.
Dessutom kan sådan datatransformation vara användbar om en databas inte är normaliserad och informationen lagras i den i en icke-optimal form. Så när du omorganiserar databasen och överför data till nya tabeller eller genererar en nödvändig datarepresentation, kan datapivot vara till hjälp, dvs. flytta värden från rader till resulterande kolumner.
Nedan är ett exempel på den gamla produkttabellen – gamla produkter och den nya – nya produkter. Det är genom omvandlingen från rader till kolumner som ett sådant resultat enkelt kan uppnås.
Här är ett exempel på en pivottabell.
Pivotering av data med hjälp av verktyg (dbForge Studio för MySQL)
Det finns applikationer som har verktyg som gör det möjligt att implementera datapivot i en bekväm grafisk miljö. Till exempel inkluderar dbForge Studio för MySQL Pivot Tables-funktionalitet som ger önskat resultat med bara några få steg.
Låt oss titta på exemplet med en förenklad ordertabell – PurchaseOrderHeader .
SKAPA TABELL PurchaseOrderHeader ( PurchaseOrderID INT(11) NOT NULL, EmployeeID INT(11) NOT NULL, VendorID INT(11) NOT NULL, PRIMÄRNYCKEL (PurchaseOrderID));INSERT PurchaseOrderHeaderID(PurchaseOrderID,PurchaseOrder)ID (PurchaseOrder)ID (PurchaseOrder) , 258, 1580);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (2, 254, 1496);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES,INSERT(3,149PurchaseOrderID EmployeeOrderID); ) VALUES (4, 261, 1650);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (5, 251, 1654);INSERT PurchaseOrderHeader(PurchaseOrderID, Employee PurchaseID, LeverantörID, INSERT OrderHeader); , EmployeeID, VendorID) VALUES (7, 255, 1678);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (8, 256, 1616);INSERT PurchaseOrderHeader(PurchaseOrderVALUE, (PurchaseOrderVALUE, (2,9)Värde-ID, (2,9)); INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (10, 250, 1602);INSERT PurchaseOrderHeader(PurchaseOrderID, EmployeeID, VendorID) VALUES (11, 258, 1540);...
Antag att vi behöver göra ett urval från tabellen och bestämma antalet beställningar som görs av vissa anställda från specifika leverantörer. Listan över anställda för vilka information behövs – 250, 251, 252, 253, 254.
En föredragen vy för rapporten är följande.
Den vänstra kolumnen VendorID visar leverantörernas ID; kolumner Emp250 , Emp251 , Emp252 , Emp253 och Emp254 visa antalet beställningar.
För att uppnå detta i dbForge Studio för MySQL behöver du:
- Lägg till tabellen som en datakälla för "pivottabell"-representationen av dokumentet. Högerklicka på PurchaseOrderHeader i Databas Explorer tabell och välj Skicka till och sedan pivottabell i popup-menyn.
- Ange en kolumn vars värden ska vara rader. Dra leverantörs-ID kolumnen till rutan 'Släpp radfält här'.
- Ange en kolumn vars värden ska vara kolumner. Dra Anställd-ID kolumnen till rutan "Släpp kolumnfält här". Du kan också ställa in ett filter för de anställda som krävs (250, 251, 252, 253, 254).
- Ange en kolumn, vars värden kommer att vara data. Dra PurchaseOrderID kolumnen till rutan "Släpp dataobjekt här".
- I egenskaperna för PurchaseOrderID kolumn, ange typen av aggregering – Antal värden .
Vi fick snabbt det resultat vi behöver.
Pivotering av data med hjälp av SQL
Naturligtvis kan datatransformation utföras med hjälp av en databas genom att skriva en SQL-fråga. Men det finns ett litet problem, MySQL har inget specifikt uttalande som tillåter detta.
T-SQL-baserat exempel för SQL Server
SqlServer och Oracle har till exempel PIVOT-operatorn som gör det möjligt att göra sådan datatransformation. Om vi arbetade med SqlServer skulle vår fråga se ut så här.
SELECT VendorID ,[250] AS Emp1 ,[251] AS Emp2 ,[252] AS Emp3 ,[253] AS Emp4 ,[254] AS Emp5FROM (SELECT PurchaseOrderID ,EmployeeID ,VendorID FROM Purchasing.PurchaseOrderPIVOTer() (PurchaseOrderID) FÖR EmployeeID IN ([250], [251], [252], [253], [254])) SOM BESTÄLLNING AV t.VendorID;
Exempel för MySQL
I MySQL måste vi använda SQL. Data bör grupperas efter leverantörskolumnen – LeverantörID , och för varje obligatorisk anställd (EmployeeID ), måste du skapa en separat kolumn med en aggregatfunktion.
I vårt fall måste vi beräkna antalet beställningar, så vi kommer att använda den aggregerade funktionen COUNT.
I källtabellen lagras informationen om alla anställda i en kolumn Anställd-ID , och vi måste beräkna antalet beställningar för en viss anställd, så vi måste lära vår aggregatfunktion att endast bearbeta vissa rader.
Den aggregerade funktionen tar inte hänsyn till NULL-värden, och vi använder denna egenhet för våra syften.
Du kan använda den villkorliga operatorn IF eller CASE som kommer att returnera ett specifikt värde för den önskade anställde, annars returnerar helt enkelt NULL; som ett resultat kommer COUNT-funktionen endast att räkna icke-NULL-värden.
Den resulterande frågan är som följer:
VÄLJ leverantörs-ID, COUNT(OM(Anställd-ID =250, Inköpsorder-ID, NULL)) AS Emp250, COUNT(OM(Anställd-ID =251, Inköpsorder-ID, NULL)) AS Emp251, COUNT(OM(Anställd-ID =252, Inköps-ID, NULL) ) AS Emp252, COUNT(IF(EmployeeID =253, PurchaseOrderID, NULL)) AS Emp253, COUNT(IF(EmployeeID =254, PurchaseOrderID, NULL)) AS Emp254FROM PurchaseOrderHeader pWHEREID BETWEENBY5 p.Employe s.Em>Eller till och med så här:
LeverantörID, COUNT(OM(Anställd-ID =250, 1, NULL)) AS Emp250, COUNT(OM(Anställd-ID =251, 1, NULL)) AS Emp251, COUNT(OM(Anställd-ID =252, 1, NULL)) AS Emp252, COUNT(IF(EmployeeID =253, 1, NULL)) AS Emp253, COUNT(IF(EmployeeID =254, 1, NULL)) AS Emp254FROM PurchaseOrderHeader pWHERE p.EmployeeID BETWEEN BY 2540;När det körs erhålls ett bekant resultat.
Automatisk datapivot, skapa sökfråga dynamiskt
Som kan ses har frågan en viss konsistens, det vill säga alla transformerade kolumner är bildade på ett liknande sätt, och för att skriva frågan måste du känna till de specifika värdena från tabellen. För att skapa en pivotfråga måste du granska alla möjliga värden och först då bör du skriva frågan. Alternativt kan du skicka denna uppgift till en server som får den att erhålla dessa värden och dynamiskt utföra rutinuppgiften.
Låt oss återgå till det första exemplet, där vi skapade den nya tabellen Produktnya från ProductsOld tabell. Där är värdena på fastigheter begränsade, och vi kan inte ens veta alla möjliga värden; vi har endast uppgifterna om var fastigheternas namn och deras värde finns lagrade. Dessa är egendomen och Värde kolumner, respektive.
Hela algoritmen för att skapa SQL-frågan handlar om att erhålla värdena, från vilka nya kolumner och sammanlänkningar av oföränderliga delar av frågan kommer att bildas.
SELECT GROUP_CONCAT( CONCAT( ' MAX(IF(Property =''', t.Property, ''', Value, NULL)) AS ', t.Property ) ) INTO @PivotQueryFROM (SELECT Property FROM ProductOld GROUP BY Egenskap) t;SET @PivotQuery =CONCAT('SELECT ProductID,', @PivotQuery, ' FROM ProductOld GROUP BY ProductID');Variabel @PivotQuery lagrar vår fråga, texten har formaterats för tydlighetens skull.
VÄLJ Produkt-ID, MAX(OM(Egenskap ='Färg', Värde, NULL)) AS Färg, MAX(OM(Egenskap ='Namn', Värde, NULL)) SOM Namn, MAX(OM(Egenskap ='Produktnummer) ', Value, NULL)) AS ProductNumber, MAX(IF(Property ='Size', Value, NULL)) AS Size, MAX(IF(Property ='SizeUnitMeasureCode', Value, NULL)) AS SizeUnitMeasureCodeFROM ProductOldGROUP BY ProductIDEfter att ha utfört det kommer vi att erhålla det önskade resultatet som motsvarar schemat i tabellen ProductsNew.
Dessutom kan frågan från variabeln @PivotQuery exekveras i skriptet med MySQL-satsen EXECUTE.PREPARE-sats FROM @PivotQuery;EXECUTE-sats;DEALLOCATE PREPARE-sats;