Transponieren Sie Zeilen und Spalten (a.k.a. pivot) nur mit einem Minimum COUNT ()?

7

Hier ist meine Tabelle 'tab_test':

%Vor%

Hier ist ein Code, der die Zeilen und Spalten transponiert, so dass ich einen Durchschnitt für "Kätzchen" und "Welpen" bekomme:

%Vor%

Die Ausgabe für den obigen Code lautet:

%Vor%

Was ich möchte, ist eine Tabelle wie die zweite, aber sie würde nur Elemente enthalten, die in der ersten Tabelle ein COUNT() von mindestens 3 hatten. Mit anderen Worten, das Ziel ist dies als Ausgabe:

%Vor%

Es gab mindestens 3 Fälle von "Kätzchen" in der ersten Tabelle.
Ist das in PostgreSQL möglich?

    
user1626730 31.10.2012, 21:59
quelle

4 Antworten

3

Hier ist eine Alternative zu dem @ bluefeet-Vorschlag , die etwas ähnlich ist, aber den Join vermeidet (stattdessen die Gruppierung auf oberster Ebene) wird auf die bereits gruppierte Ergebnismenge angewendet):

%Vor%     
Andriy M 31.10.2012, 22:32
quelle
11

CASE

Wenn Ihr Fall so einfach ist wie gezeigt, macht eine CASE Anweisung:

%Vor%

Es spielt keine Rolle, ob Sie sum() , max() oder min() als Aggregatfunktion in der äußeren Abfrage verwenden. Sie alle ergeben in diesem Fall den gleichen Wert.

SQL Fiddle

crosstab()

Bei mehr Kategorien wird es einfacher mit einer crosstab() Abfrage. Dies sollte für größere Tabellen auch schneller sein.

Sie müssen das zusätzliche Modul tablefunc (einmal pro Datenbank) installieren. Seit Postgres 9.1 ist das so einfach wie:

%Vor%

Details in dieser verwandten Antwort:

%Vor%

Kein sqlfiddle für diesen, da die Site keine zusätzlichen Module zulässt.

Benchmark

Um meine Behauptungen zu überprüfen, habe ich einen schnellen Benchmark mit fast echten Daten in meiner kleinen Testdatenbank durchgeführt. PostgreSQL 9.1.6. Test mit EXPLAIN ANALYZE , best of 10:

Test-Setup mit 10020 Zeilen:

%Vor%

Ergebnisse:

@bluefeet
Gesamtlaufzeit: 95.401 ms

@wildplasser (unterschiedliche Ergebnisse, enthält Zeilen mit count <= 3 )
Gesamtlaufzeit: 64.497 ms

@Andreiy (+ ORDER BY )
&Ampere; @ Erwin1 - CASE (beide ungefähr gleich)
Gesamtlaufzeit: 39.105 ms

@ Erwin2 - crosstab()
Gesamtlaufzeit: 17.644 ms

Weitgehend proportionale (aber irrelevante) Ergebnisse mit nur 20 Zeilen. Only @ wildplassers CTE hat mehr Overhead und Spikes ein wenig.

Mit mehr als einer Handvoll Zeilen übernimmt crosstab() schnell die Führung. @ Andreiy Abfrage führt etwa genauso wie meine vereinfachte Version, Aggregatfunktion in äußeren SELECT ( min() , max() , sum() ) macht keinen messbaren Unterschied (nur zwei Zeilen pro Gruppe).

Alles wie erwartet, keine Überraschungen, nimm mein Setup und versuche es @home.

    
Erwin Brandstetter 31.10.2012 23:40
quelle
3

Suchen Sie das?

%Vor%

Siehe SQL Geige mit Demo

    
Taryn 31.10.2012 22:05
quelle
2
%Vor%     
wildplasser 31.10.2012 22:55
quelle

Tags und Links