Ich habe eine Tabelle mit Bestellungen
Column | Type | Modifiers
------------+-----------------------------+-----------------------------------------------------
id | integer | not null default nextval('orders_id_seq'::regclass)
client_id | integer | not null
start_date | date | not null
end_date | date |
order_type | character varying | not null
Die Daten haben nicht überlappende Daueraufträge für eine client_id und gelegentlich einen temporären Auftrag, der den Dauerauftrag am Startdatum überschreibt, wenn sie eine übereinstimmende client_id haben. Es gibt Einschränkungen auf Anwendungsebene, die verhindern, dass sich Aufträge desselben Typs überschneiden.
id | client_id | start_date | end_date | order_type
----+-----------+------------+------------+------------
17 | 11 | 2014-02-05 | | standing
18 | 15 | 2014-07-16 | 2015-07-19 | standing
19 | 16 | 2015-04-01 | | standing
20 | 16 | 2015-07-18 | 2015-07-18 | temporary
Zum Beispiel hat auf 2015-07-18
Client 16 die Bestellung Nr. 20 als aktive Bestellung, da sie den Dauerauftrag Nr. 19 überschreibt. Mit einigem Aufwand fand ich eine effiziente Möglichkeit, aktive Bestell-IDs an einem Datum abzufragen.
SELECT id from (
SELECT
id,
first_value(id) OVER (PARTITION BY client_id ORDER BY order_type DESC) active_order_id
FROM orders
WHERE start_date <= ? and (end_date is null OR end_date >= ?)
) active_orders
WHERE id = active_order_id
Wenn Sie dies 2015-07-18
als Platzhalter abfragen , erhalten Sie
id
----
17
18
20
Der Abfrageplan für diese Abfrage ist im Vergleich zu einigen meiner anderen Ideen (z. B. Unterabfragen, bei denen die Anzahl der temporären Bestellungen für einen Kunden an einem Datum gezählt wird) recht klein und ich bin ziemlich zufrieden damit. (Das Design des Tisches, ich bin nicht begeistert)
Jetzt muss ich alle aktiven Bestellungen für einen Datumsbereich finden, die mit den Daten verknüpft sind, an denen sie aktiv sind. Zum Beispiel möchte ich mit dem Datumsbereich von 2015-07-18
bis 2015-07-19
das folgende Ergebnis.
active_date | id
------------+----
2015-07-18 | 17
2015-07-18 | 18
2015-07-18 | 20
2015-07-19 | 17
2015-07-19 | 18
2015-07-19 | 19
Bestellung 20 überschreibt Bestellung 19 ein, 2015-07-18
aber nicht ein 2015-07-19
.
Ich habe festgestellt, dass generate_series()
ich eine Reihe von Daten generieren kann, aber ich habe keine Ahnung, wie ich das damit verbinden soll, um eine Tabelle mit Daten und Bestell-IDs zu erhalten. Meine Vermutung ist ein Cross Join, aber ich kann nicht herausfinden, wie das unter diesen Umständen funktioniert.
Vielen Dank
UPDATE Es wurde eine SQL-Geige hinzugefügt .