Здесь может быть некоторая возможность для рефакторинга (особенно если вы используете более новую версию mysql, которая поддерживает оконные функции). Это должно привести вас к тому, что:
Получите последние transaction_id
для каждого invoice_id
SELECT transaction_id, invoice_id
FROM jos_payplans_transactions jpt
WHERE create_date =
(
SELECT max(create_date)
FROM jos_payplans_transactions
WHERE jpt.invoice_id = invoice_id
)
Получите последние object_id
для каждого order_id
:
SELECT invoice_id, object_id
FROM jos_payplans_invoice jpi
WHERE create_date =
(
SELECT max(create_date)
FROM jos_payplans_invoice
WHERE jpi.object_id = object_id
)
Соберите все вместе:
SELECT
a.subscription_id,
b.invoice_id,
c.transaction_id
FROM jos_payplans_subscription as a
LEFT OUTER JOIN
(
SELECT invoice_id, object_id
FROM jos_payplans_invoice jpi
WHERE create_date =
(
SELECT max(create_date)
FROM jos_payplans_invoice
WHERE jpi.object_id = object_id
)
) b on a.order_id = b.object_id
LEFT OUTER JOIN
(
SELECT transaction_id, invoice_id
FROM jos_payplans_transactions jpt
WHERE create_date =
(
SELECT max(create_date)
FROM jos_payplans_transactions
WHERE jpt.invoice_id = invoice_id
)
) c on b.invoice_id = c.invoice_id;
Более новые версии Mysql (8.0+) могут обрабатывать оконные функции, что поможет повысить производительность здесь, поскольку выполняется только одно сканирование каждой таблицы. необходимо:
SELECT
a.subscription_id,
b.invoice_id,
c.transaction_id
FROM jos_payplans_subscription as a
LEFT OUTER JOIN
(
SELECT invoice_id,
object_id,
ROW_NUMBER() OVER (PARTITION BY object_id ORDER BY create_date) as rn
FROM jos_payplans_invoice jpi
) b on a.order_id = b.object_id
AND b.rn = 1
LEFT OUTER JOIN
(
SELECT transaction_id,
invoice_id ,
ROW_NUMBER() OVER (PARTITION BY invoice_id ORDER BY create_date) as rn
FROM jos_payplans_transactions jpt
) c on b.invoice_id = c.invoice_id
AND c.rn = 1;