Вместо группировки, затем объединения, затем группировки снова, почему бы не объединить таблицы заказов и работать оттуда:
SELECT c1.customer ,MAX(s2.dt_created) AS last_order_date
FROM customers c1
INNER JOIN (select customer, dt_created from archive_orders
union all select customer, dt_created from orders) s2
ON c1.customer = s2.customer
GROUP BY c1.customer
Помните, что в SQL ваша задача - сообщить системе , что вы хотите , а не , какие шаги / процедуры нужно выполнить, чтобы получить эти результаты . Вышеприведенное, логически, описывает то, что мы хотим - мы хотим, чтобы дата последнего заказа от заказов каждого клиента, и нас не волнует, был ли это заархивированный заказ или неархивированный.
Так как мы собираемся уменьшить информацию о заказе до одной строки (для каждого клиента) во время поведения GROUP BY
, нам также не потребуется UNION
для удаления дубликатов, поэтому Я перешел на UNION ALL
.
(Признаюсь, я не мог реально увидеть, что ORDER BY
должен был добавить к миксу в этот момент, поэтому я не пытался включить его сюда. Если это входит в CTE, то подумайте тот факт, что CTE, как и таблицы и представления, не имеют присваиваемого порядка . Единственное условие ORDER BY
, которое влияет на порядок строк результатов, - это условие, применяемое к крайнему / последнему SELECT
)
Предоставление orders
приоритета над archived_orders
:
;With CTE1 as (
SELECT c1.customer,group,MAX(s2.dt_created) as MaxInGroup
FROM customers c1
INNER JOIN (select customer, dt_created,2 as group from archive_orders
union all select customer, dt_created,1 from orders) s2
ON c1.customer = s2.customer
GROUP BY c1.customer,group
), CTE2 as (
SELECT *,ROW_NUMBER() OVER (PARTITION BY customer ORDER BY group) as rn
from CTE2
)
select * from CTE2 where rn = 1