Хотя другие упоминают об использовании MAX () с возрастающей последовательностью, лучше избегать этого, если это возможно.Поскольку у вас есть ACTIONS_HISTORY_DT с фактическим значением даты, этот вариант лучше использовать (и индекс в этом столбце будет способствовать повышению производительности).
Использование MAX () с последовательностью может привести к прерыванию запроса в некоторых обстоятельствах за пределамиконтроль разработчика (например, перемещение в кластеризованную базу данных), когда последовательности больше не находятся в техническом порядке в возрастающем порядке.
Кроме того, вы также можете использовать аналитические функции, чтобы уменьшить потребность в самосоединениях.См. О функциях SQL: аналитические функции и FIRST_VALUE на oracle.com для получения дополнительной информации.
Я бы предложил этот запрос:
WITH recent_actions AS
(SELECT DISTINCT ah.call_id,
FIRST_VALUE(ah.actions_history_id) OVER
(PARTITION BY ah.call_id
ORDER BY ah.actions_history_dt DESC ROWS UNBOUNDED PRECEDING
) AS latest_action_id
FROM actions_history ah)
SELECT c.call_id, r.latest_action_id
FROM call c
LEFT JOIN recent_actions r ON(r.call_id = c.call_id);
Поскольку в запросе используется общее табличное выражение (CTE) для извлечения CALL_ID и последнего ACTIONS_HISTORY_ID, вы можете использовать эти идентификаторы для добавления другого внешнего соединения в ACTIONS_HISTORY, если вам нужно больше столбцов из истории, возвращаемой в запросе:
WITH recent_actions AS
(SELECT DISTINCT ah.call_id,
FIRST_VALUE(ah.actions_history_id) OVER
(PARTITION BY ah.call_id
ORDER BY ah.actions_history_dt DESC ROWS UNBOUNDED PRECEDING
) AS latest_action_id
FROM actions_history ah)
SELECT c.call_id, r.latest_action_id, h.description, h.duration, h.caller_id
FROM call c
LEFT JOIN recent_actions r ON(r.call_id = c.call_id)
LEFT JOIN actions_history h ON(h.actions_history_id = r.latest_action_id;