Я считаю, что без какой-либо записи в таблице orders
не может быть записи в таблице orders_products
и order_status_history
.Поэтому я бы изменил порядок объединения таблиц для простоты понимания.Более того, нет необходимости в LEFT JOIN
, так как мы пытаемся выбрать строки для определенного продукта (следовательно, строки должны существовать в таблице продуктов), и для определенного order_status (следовательно, строки должны существовать в таблице истории состояний).Поэтому я заменит все LEFT JOIN
в запросе на INNER JOIN
.
Теперь, чтобы получить последнюю updatedat
строку, соответствующую определенному статусу, нам нужно будет использовать Производная таблица.В этом подзапросе мы получим самое последнее значение updatedat
для каждого заказа, когда статус будет 3 .
В конце концов мы соответствующим образом присоединим этот набор результатов подзапроса к основным таблицам,чтобы получить данные, соответствующие последнему значению строки updatedat
.
Также, как правило, рекомендуется перевести условия WHERE
в предложение join ON
для простоты понимания.Кроме того, в будущем, когда вы переключитесь с INNER JOIN
на LEFT JOIN
и т. Д., Вы можете легко изменить, не беспокоясь о ненужной фильтрации, происходящей из-за WHERE
.
Попробуйте выполнить следующий запрос: Просмотр на БД Fiddle
SELECT
o.id,
op.quantity,
osh.updatedat
FROM
orders AS o
JOIN order_products AS op
ON op.order_id = o.id AND
op.productid = 1
JOIN order_status_history AS osh
ON osh.order_id = o.id
JOIN (SELECT order_id,
MAX(updatedat) AS max_updated_at
FROM order_status_history
WHERE order_status_id = 3
GROUP BY order_id
) AS dt
ON dt.order_id = o.id AND
dt.max_updated_at = osh.updatedat;
Результат:
| id | quantity | updatedat |
| --- | -------- | ------------------- |
| 1 | 1 | 2017-05-22 18:45:50 |
| 1 | 2 | 2017-05-22 18:45:50 |
| 1 | 2 | 2017-05-22 18:45:50 |
| 1 | 10 | 2017-05-22 18:45:50 |
Кроме значений updatedat
, есливам не нужно получать какие-либо другие столбцы из таблицы order_status_history
, вы можете дополнительно оптимизировать запрос, избавившись от соединения с таблицей order_status_history
Query # 2
SELECT
o.id,
op.quantity,
dt.max_updated_at AS updatedat
FROM
orders AS o
JOIN order_products AS op
ON op.order_id = o.id AND
op.productid = 1
JOIN (SELECT order_id,
MAX(updatedat) AS max_updated_at
FROM order_status_history
WHERE order_status_id = 3
GROUP BY order_id
) AS dt
ON dt.order_id = o.id;
Результат:
| id | quantity | updatedat |
| --- | -------- | ------------------- |
| 1 | 1 | 2017-05-22 18:45:50 |
| 1 | 2 | 2017-05-22 18:45:50 |
| 1 | 2 | 2017-05-22 18:45:50 |
| 1 | 10 | 2017-05-22 18:45:50 |