У меня есть четыре таблицы, которые связаны. В таблице itemStatus может быть несколько записей для каждого элемента корзины, чтобы показать его историю (например, куплено, обработано, отправлено, доставлено). Таблица «Магазин» вводит название товаров корзины. Таблица Order определяет все элементы корзины в заказе.
Чтобы показать последний статус (а не всю историю) каждого элемента корзины в заказе, мне нужно получить только последнюю запись для itemStatus. Я использую подзапрос для получения записей таблицы itemStatus, но не могу понять, как получить последнюю запись. Играя с приведенным ниже кодом, я всегда получаю первую запись:
SELECT
tblOrders.id,tblOrders.status as orderStatus,tblOrders.created,tblCart.id AS cartID,tblCart.status AS cartStatus,tblCart.qty,tblCart.price,tblShop.title,tblItem.itemStatus
FROM
".PREFIX."Orders tblOrders
LEFT JOIN
".PREFIX."Cart tblCart ON tblOrders.id=tblCart.OID
LEFT JOIN
".PREFIX."Shop tblShop ON tblCart.PID=tblShop.id
LEFT JOIN
(SELECT
CID,status as itemStatus
FROM
".PREFIX."ItemStatus
WHERE
status IN ('pending','refunded','cancelled','purchased','backordered','shipping','delivered')
GROUP BY CID
ORDER BY
created DESC
) tblItem ON tblCart.id=tblItem.CID
WHERE
tblOrders.status<>'disabled' AND tblCart.status='purchased' AND tblCart.BID='".$gbl_user['id']."'
ORDER BY
tblOrders.updated DESC
Как показано выше, я попытался использовать предложение «GROUP BY», чтобы ограничить количество записей, возвращаемых подзапросом, но это не дало желаемых результатов. Я также попытался поместить предложение «LIMIT 1» в подзапрос, но это ограничивает количество возвращаемых записей до 1 (поэтому любые другие элементы корзины не получают статус). Любая помощь будет оценена по достоинству!
ОБНОВИТЬ:
В соответствии с маркировкой дублирования я попытался обновить код, используя оператор MAX() и удалив «ORDER BY» следующим образом:
SELECT
tblOrders.id,tblOrders.status as orderStatus,tblOrders.created,tblCart.id AS cartID,tblCart.status AS cartStatus,tblCart.qty,tblCart.price,tblShop.title,tblItem.itemStatus
FROM
".PREFIX."Orders tblOrders
LEFT JOIN
".PREFIX."Cart tblCart ON tblOrders.id=tblCart.OID
LEFT JOIN
".PREFIX."Shop tblShop ON tblCart.PID=tblShop.id
LEFT JOIN
(SELECT
CID,status as itemStatus,MAX(created) as itemCreated
FROM
".PREFIX."ItemStatus
WHERE
status IN ('pending','refunded','cancelled','purchased','backordered','shipping','delivered')
GROUP BY CID
) tblItem ON tblCart.id=tblItem.CID
WHERE
tblOrders.status<>'disabled' AND tblCart.status='purchased' AND tblCart.BID='".$gbl_user['id']."'
ORDER BY
tblOrders.updated DESC
ОБНОВЛЕНИЕ 2:
Я предоставил фактический код, который работает для решения проблемы, но по какой-то причине он не был одобрен. Я отправляю правильный код ниже:
SELECT
tblOrders.id, tblOrders.status as orderStatus, tblOrders.created,
tblCart.id AS cartID, tblCart.status AS cartStatus,tblCart.qty,
tblCart.price, tblShop.title, tblItem.status as itemStatus
FROM
".PREFIX."Orders tblOrders
LEFT JOIN
".PREFIX."Cart tblCart ON tblOrders.id=tblCart.OID
LEFT JOIN
".PREFIX."Shop tblShop ON tblCart.PID=tblShop.id
LEFT JOIN
".PREFIX."ItemStatus tblItem ON tblCart.id=tblItem.CID
JOIN (
SELECT
CID, MAX(created) AS maxCreated
FROM
".PREFIX."ItemStatus
WHERE
status IN ('pending','refunded','cancelled','purchased','backordered','shipping','delivered')
GROUP BY
CID
) tblMaxItem ON tblItem.CID=tblMaxItem.CID AND tblItem.created=tblMaxItem.maxCreated
WHERE
tblOrders.status<>'disabled' AND tblCart.status='purchased' AND tblCart.BID='".$gbl_user['id']."'
ORDER BY
tblOrders.updated DESC
@Barmar Итак, основываясь на повторяющейся маркировке, я просмотрел сообщение, на которое вы ссылались, и похоже, что я должен использовать оператор MAX(). Я пробовал несколько вариантов и до сих пор не могу заставить это работать. Кто-нибудь хочет помочь?
Подзапрос, к которому вы присоединяетесь, должен использовать один из методов в этих ответах, чтобы получить последнюю строку для каждого элемента. Если вы опубликуете то, что вы пробовали, я снова открою, и мы сможем показать, как это исправить. Но мы не собираемся писать его для вас с нуля.
@ Бармар, вот! Взломать!
Похоже, вы действительно не читали там ответы. Разве вы не заметили, что они присоединяются к таблице с помощью подзапроса, использующего MAX()? У вас есть подзапрос MAX(), но не сама таблица.
Обновленная версия использует MAX() в подзапросе.
@Barmar Обновленная версия использует MAX() в подзапросе. Что значит "не сам стол"? Пост, на который вы указали, присоединяется сам к себе. Это гораздо более сложный запрос, чем опубликованный.
Как этот запрос: SELECT a.id, a.rev, a.contents FROM YourTable a INNER JOIN ( SELECT id, MAX(rev) rev FROM YourTable GROUP BY id ) b ON a.id = b.id AND a.rev = b.rev Он объединяет YourTable с подзапросом, который содержит MAX(rev)
Вы присоединяете их к таблицам, которые у вас уже есть в исходном запросе.
@Barmar Это просто копирование запроса из указанного поста. Это, очевидно, не помогает, так как я просмотрел это дюжину раз на данный момент. Как уже говорилось, этот запрос является самообъединяющимся. Попробуем получить разрешение. Вы говорите, что я должен сделать два подзапроса? В основном добавление еще одного подзапроса к подзапросу, чтобы они могли быть объединены?
Я добавил код. Последние два соединения структурированы точно так же, как этот образец запроса.






Вам нужно присоединиться как к ItemStatus, так и к подзапросу, который получает последнюю дату для каждого элемента, чтобы вы могли получить другие столбцы столбцов из этой строки.
SELECT
tblOrders.id, tblOrders.status as orderStatus, tblOrders.created,
tblCart.id AS cartID, tblCart.status AS cartStatus,tblCart.qty,
tblCart.price, tblShop.title, tblItem.status AS itemStatus
FROM
".PREFIX."Orders tblOrders
LEFT JOIN
".PREFIX."Cart tblCart ON tblOrders.id=tblCart.OID
LEFT JOIN
".PREFIX."Shop tblShop ON tblCart.PID=tblShop.id
LEFT JOIN
".PREFIX."ItemStatus tblItem ON tblCart.id=tblItem.CID
LEFT JOIN (
SELECT
CID, MAX(created) AS maxCreated
FROM
".PREFIX."ItemStatus
WHERE
status IN ('pending','refunded','cancelled','purchased','backordered','shipping','delivered')
GROUP BY
CID
) tblMaxItem ON tblItem.CID=tblMaxItem.CID AND tblItem.created=tblMaxItem.maxCreated
WHERE
tblOrders.status<>'disabled' AND tblCart.status='purchased' AND tblCart.BID='".$gbl_user['id']."'
ORDER BY
tblOrders.updated DESC
Спасибо за публикацию ответа! Я обновил код, чтобы исправить синтаксические ошибки. После внедрения обновленного кода я по-прежнему не получаю никаких отличий от исходного кода. Есть предположения?
Я также попытался изменить «JOIN» на «INNER JOIN», как показано в упомянутом сообщении, но никаких изменений еще нет...
JOIN и INNER JOIN — это одно и то же.
Последним JOIN может быть LEFT JOIN, так как вы используете LEFT JOIN в предыдущей строке.
Почему вы добавили status в подзапрос? Весь смысл в том, что вы должны получить status из tblItem, а не из подзапроса.
О, я думал, что это запрос, из которого нужно извлечь информацию (поскольку он должен возвращать только последнюю единственную запись). В противном случае я получал ошибку SQL «1054: Неизвестный столбец« tblItem.itemStatus »в« списке полей »». Я исправил код выше и принял ваш ответ. Большое спасибо, Бармар!
Должно быть tblItem.status.