Ich habe eine Tabelle in meiner PG db, die ungefähr so aussieht:
%Vor%Jedes referenzierte Widget hat viele dieser Elemente. Es ist immer 1 pro Tag pro Widget, aber es gibt Lücken.
Was ich erhalten möchte, ist ein Ergebnis, das alle Widgets für jedes Datum seit X enthält. Die Daten werden über generate series eingefügt:
%Vor%Wenn es keinen Eintrag für ein Datum für eine bestimmte widget_id gibt, möchte ich das vorherige verwenden. Also sagen Sie das Widget 1337 hat keinen Eintrag am 2012-05-10, aber am 2012-05-08, dann möchte ich, dass das Resultset auch den Eintrag 2012-05-08 am 2012-05-10 anzeigt:
%Vor%Irgendwann möchte ich dies in eine Ansicht herunterkochen, damit ich konsistente Datensätze pro Tag habe, die ich leicht abfragen kann.
Bearbeiten: Die Beispieldaten und das Ergebnisergebnis wurden klarer gemacht
Zuerst von allen, Sie können einen viel einfacheren generate_series()
-Tabellenausdruck haben. Gleichbedeutend mit Ihrem (außer absteigender Reihenfolge, das dem Rest Ihrer Frage sowieso widerspricht):
Der Typ date
wird bei der Eingabe automatisch in timestamptz
umgewandelt. Der Rückgabetyp ist timestamptz
in beide Richtungen. Ich verwende unten eine Unterabfrage, sodass ich sofort auf die Ausgabe in date
umstellen kann.
Weiter , max()
als Fensterfunktion gibt genau das zurück, was Sie brauchen: Der höchste Wert seit frame beginnt, NULL
-Werte zu ignorieren. Darauf aufbauend erhalten Sie eine radikal einfache Abfrage.
Sehr wahrscheinlich schneller als mit CROSS JOIN
oder WITH RECURSIVE
:
Mit dieser Abfrage können Sie beliebige Spalten von score
in die endgültige SELECT
-Liste setzen. Ich stelle s. * Zur Vereinfachung. Wählen Sie Ihre Spalten.
Wenn Sie Ihre Ausgabe mit dem ersten Tag beginnen möchten, der tatsächlich eine Punktzahl hat, ersetzen Sie einfach die letzte LEFT JOIN
durch JOIN
.
Hier verwende ich CROSS JOIN
, um für jedes Widget an jedem Datum eine Zeile zu erzeugen.
Unter Verwendung Ihrer Tabellenstruktur habe ich den folgenden rekursiven CTE erstellt, der mit Ihrem MIN (For_Date) beginnt und inkrementiert, bis er den MAX (For_Date) erreicht. Nicht sicher, ob es einen effizienteren Weg gibt, aber das scheint gut zu funktionieren:
%Vor%Hier ist die SQL Fiddle .
Und die zurückgegebenen Ergebnisse (formatieren Sie das Datum wie Sie möchten):
%Vor%Beachten Sie, dass davon ausgegangen wird, dass das Feld "For_Date" ein Datum ist. Wenn es eine Uhrzeit enthält, müssen Sie möglicherweise stattdessen das Intervall "1 Tag" in der obigen Abfrage verwenden.
Hoffe, das hilft.
Tags und Links sql postgresql