Hallo,
ich suche eine Möglichkeit, folgendes Problem zu lösen (ein Ansatz würde mir schon reichen):
Ich habe Plakatflächen, die mit verschiedenen Kampagnen belegt werden können. Jeweils mehrere Plakatflächen sind zu einem Standort zusammengefasst. Ich möchte jetzt wissen, wieviele Plakatflächen an einem Standort für einen gewissen Zeitraum maximal belegt werden können.
Zur Illustration versuche ich das mal als Tabelle darzustellen:
Die Tabelle stellt alle Kampagnen an einem Standort dar. Die Kampagnen A, B und C sind bereits mit unterschiedlichen Zeiträumen eingebucht. Die Kampagne D soll neu eingebucht werden. Nun möchte ich wissen, wieviele Flächen im Zeitraum 3 - 6 belegt sind (die freien Flächen erhalte ich durch einfach Subtraktion der belegten von den gesamten Flächen).
Die Lösung soll in diesem Fall “3” lauten: Das Maximum von Sum_1 für den betrachteten Zeitraum.
In meiner Lösung, die ich bisher verwende, Summiere ich alle belegten Flächen der Kampagnen A - C, die in den Zeitraum der Kampagne D “hineinragen” auf und erhalte “4” (Sum_2), was natürlich klar ist, da ich bei dieser Methode die Kampagnen A + B aufsummiere, was ich eigentlich nicht darf!
Die einzige Möglichkeit, die mir bisher eingefallen ist, ich schaue mir jeden einzelnen Tag im Zeitraum an, also 3, 4, 5, 6 und errechne die Zahl der belegten Flächen. Das Maximum aus allen Tagen ist dann die gesuchte Zahl.
Allerdings muss ich dies in einem externen Skript machen (PHP), was natürlich sehr lange dauern kann.
Gibt es vielleicht auch eine Möglichkeit, mit eine geschickten View oder Funktion (ob plpgsql oder anderes) diese Berechnung zu vereinfachen?
Die SQL-Tabelle mit den Belegungen sieht (im wesentlichen) so aus:
CREATE TABLE belegung(
id INTEGER PRIMARY KEY,
outlet INTEGER REFERENCES outlets,
kampagne INTEGER REFERENCES kampagnen,
flaechen INTEGER,
beginn DATE,
ende DATE
)
Die Spalte outlet verweist auf die Tabelle mit den Standorten, die Spalte kampagne auf die Tabelle mit den Kampagnen.
In meiner bisherigen Lösung verwende ich dann die folgende Funktion, um die Anzahl der belegten Flächen zu ermitteln:
CREATE FUNCTION belegt(
integer, -- $1 outlet_id
integer, -- $2 kampagnen_id
date, -- $3 von
date -- $4 bis
)
RETURNS INTEGER
AS '
SELECT
SUM(flaechen)
FROM
belegung
WHERE
outlet = $1 AND
kampagne = $2 AND
((beginn >= $3 AND beginn <4>= $3 AND ende <= $4))
GROUP BY
outlet
' LANGUAGE 'sql';
(Bitte nicht schlagen, wenn syntaktische Fehler in meinem Code sind, der Original-Code ist komplexer und ich habe ihn hier auf das wesentliche reduziert)
Also, nochmal zum Schluss: Hat jemand eine Idee für einen Ansatz? Ich möchte gerne eine Lösung haben, die ich direkt unter PostgreSQL laufen lassen kann, so dass die Clients, die darauf zugreifen müssen, möglichst “dumm” sein können und die eigentliche Logik in der Datenbank liegt, also eine View oder eine Funktion.
(btw. die Formel wird merkwürdig dargestellt - ich weis - aber die Forensoftware verunstaltet den Code so merkwürdig… ;-()