Ho una tabella di ordini
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
I dati hanno ordini permanenti non sovrapposti per un client_id e, occasionalmente, un ordine temporaneo che sovrascrive l'ordine permanente alla sua data_inizio quando hanno un client_id corrispondente. Esistono vincoli a livello di applicazione che impediscono la sovrapposizione di ordini dello stesso tipo.
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
Ad esempio, sul 2015-07-18
client 16 ha l'ordine n. 20 come ordine attivo perché sovrascrive l'ordine permanente n. 19. Con un po 'di confusione ho trovato un modo efficiente di interrogare gli ID degli ordini attivi in una data.
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
Se lo richiedi 2015-07-18
come segnaposto, otterrai
id
----
17
18
20
Il piano di query su questa query rispetto ad alcune delle mie altre idee (come le query secondarie che contano il numero di ordini temporanei per un cliente in una data) è piuttosto piccolo e ne sono abbastanza soddisfatto. (il design del tavolo, non sono elettrizzato)
Ora ho bisogno di un per trovare tutti gli ordini attivi per un intervallo di date unito alle date in cui sono attivi. Ad esempio, con l'intervallo di date di 2015-07-18
a 2015-07-19
vorrei il seguente risultato.
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
L'ordine 20 ha la precedenza sull'ordine 19, 2015-07-18
ma non su 2015-07-19
.
Ho scoperto generate_series()
che posso generare un intervallo di date, ma non ho idea di come unirmi a questo per ottenere una tabella di date e ordinare gli ID. Il mio sospetto è un cross join ma non riesco a capire come farlo funzionare in questa circostanza.
Grazie
AGGIORNAMENTO Aggiunto un violino sql .