Transponieren von Zeilen und Spalten (eine.k.ein. pivot) nur mit einem minimum COUNT()?
Hier ist meine Tabelle 'tab_test':
year animal price
2000 kittens 79
2000 kittens 93
2000 kittens 100
2000 puppies 15
2000 puppies 32
2001 kittens 31
2001 kittens 17
2001 puppies 65
2001 puppies 48
2002 kittens 84
2002 kittens 86
2002 puppies 15
2002 puppies 95
2003 kittens 62
2003 kittens 24
2003 puppies 36
2003 puppies 41
2004 kittens 65
2004 kittens 85
2004 puppies 58
2004 puppies 95
2005 kittens 45
2005 kittens 25
2005 puppies 15
2005 puppies 35
2006 kittens 50
2006 kittens 80
2006 puppies 95
2006 puppies 49
2007 kittens 40
2007 kittens 19
2007 puppies 81
2007 puppies 38
2008 kittens 37
2008 kittens 51
2008 puppies 29
2008 puppies 72
2009 kittens 84
2009 kittens 26
2009 puppies 49
2009 puppies 34
2010 kittens 75
2010 kittens 96
2010 puppies 18
2010 puppies 26
2011 kittens 35
2011 kittens 21
2011 puppies 90
2011 puppies 18
2012 kittens 12
2012 kittens 23
2012 puppies 74
2012 puppies 79
Hier ist etwas code, der sich um die Umsetzung der Zeilen und Spalten, so erhalte ich im Durchschnitt für 'Kätzchen' und 'Welpen':
SELECT
year,
AVG(CASE WHEN animal = 'kittens' THEN price END) AS "kittens",
AVG(CASE WHEN animal = 'puppies' THEN price END) AS "puppies"
FROM tab_test
GROUP BY year
ORDER BY year;
Die Ausgabe für den code oben ist:
year kittens puppies
2000 90.6666666666667 23.5
2001 24.0 56.5
2002 85.0 55.0
2003 43.0 38.5
2004 75.0 76.5
2005 35.0 25.0
2006 65.0 72.0
2007 29.5 59.5
2008 44.0 50.5
2009 55.0 41.5
2010 85.5 22.0
2011 28.0 54.0
2012 17.5 76.5
Was ich möchte, ist eine Tabelle wie die zweite, aber es würde nur die Elemente enthalten, die eine COUNT()
von mindestens 3 in der ersten Tabelle. In anderen Worten, das Ziel ist diese als Ausgang:
year kittens
2000 90.6666666666667
Gab es mindestens 3 Instanzen von "Kätzchen" in der ersten Tabelle.
Ist das möglich in der PostgreSQL?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist eine alternative zu @bluefeet Vorschlag, das ist etwas ähnlich, aber vermeidet die join (anstelle der oberen Ebene Gruppierung angewendet wird, um die bereits gruppierten Ergebnismenge):
CASE
Wenn Ihr Fall ist so einfach, wie gezeigt, eine
CASE
Anweisung tun:Egal, ob Sie
sum()
,max()
odermin()
als Aggregat-Funktion in der äußeren Abfrage. Sie alle führen den gleichen Wert in diesem Fall.SQL Fiddle
crosstab()
Mit mehr Kategorien wird es einfacher sein mit einem
crosstab()
Abfrage. Dies sollte auch schneller für größere Tabellen.Zu installieren, müssen Sie das zusätzliche Modul tablefunc (einmal pro Datenbank). Da Postgres 9.1, das so einfach wie:
Details in diesem Zusammenhang zu beantworten:
Kein sqlfiddle für diesen einen, weil die Website nicht ermöglichen zusätzliche Module.
Benchmark
Zu überprüfen, meine Forderungen, ich lief ein schnelles benchmark mit der Nähe zu den realen Daten in meinem kleinen test-Datenbank. PostgreSQL 9.1.6. Test mit
EXPLAIN ANALYZE
am besten von 10:Test-setup mit 10020 Zeilen:
Ergebnisse:
@bluefeet
Gesamt-Laufzeit: 95.401 ms
@wildplasser (unterschiedliche Ergebnisse, enthält Zeilen mit
count <= 3
)Gesamt-Laufzeit: 64.497 ms
@Andreiy (+
ORDER BY
)& @Erwin1 -
CASE
(führen beide zu den gleichen)Gesamt-Laufzeit: 39.105 ms
@Erwin2 -
crosstab()
Gesamt-Laufzeit: 17.644 ms
Weitgehend proportional (aber irrelevante) Ergebnisse mit nur 20 Zeilen. Nur @wildplasser CTE hat mehr Verwaltungsaufwand und-Spitzen ein wenig.
Mit mehr als eine Handvoll Zeilen,
crosstab()
schnell nimmt führen.@Andreiy die Abfrage ausführt, ungefähr das gleiche wie meine vereinfachte version, die Aggregat-Funktion in der äußeren
SELECT
(min()
,max()
,sum()
) macht keinen messbaren Unterschied (nur zwei Zeilen pro Gruppe).Alles wie erwartet, keine überraschungen, nimm mein setup und versuchen Sie es @home.
CASE
version sollte genauso schnell oder schneller - mit Ausnahme der fehlendenORDER BY
im @Andriy version. Hmm.. vielleichtsum()
ist langsamer alsmax()
.. aber das sollte kaum relevant sein. Diecrosstab()
version wäre schneller, bei komplexeren Fällen / größeren Tabellen.Ist es das, was Sie suchen:
Sehen SQL Fiddle mit Demo