У меня есть стол заказов
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
Данные имеют неперекрывающиеся постоянные заказы для client_id и иногда временный заказ, который переопределяет постоянный заказ на их start_date, когда они имеют совпадающий client_id. Существуют ограничения уровня приложения, которые не допускают перекрытия заказов одного типа.
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
Например, на 2015-07-18клиенте 16 есть заказ № 20, поскольку он является активным заказом, потому что он отменяет постоянный заказ № 19. С некоторой суетой я нашел эффективный способ запрашивать идентификаторы активных заказов на дату.
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
Если вы запросите это 2015-07-18в качестве заполнителей, вы получите
id
----
17
18
20
План запроса по этому запросу по сравнению с некоторыми другими моими идеями (такими как подзапросы, подсчитывающие количество временных заказов для клиента на дату) довольно мал, и я очень доволен этим. (дизайн стола, я не в восторге)
Теперь мне нужно найти все активные заказы для диапазона дат, объединенного с датами, в которые они активны. Например, с диапазоном дат 2015-07-18до 2015-07-19я бы хотел следующий результат.
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
Порядок 20 переопределяет порядок 19, 2015-07-18но не включен 2015-07-19.
Я обнаружил, generate_series()что могу сгенерировать диапазон дат, но я понятия не имею, как соединить это с этим, чтобы получить таблицу дат и идентификаторы заказов. Я предчувствую, что это взаимное объединение, но я не могу понять, как заставить это работать в таких условиях.
Спасибо
ОБНОВЛЕНИЕ Добавлена скрипта sql .