Я использую «ответить на мой вопрос», потому что мне нужно опубликовать результаты ваших запросов.Итак.
К сожалению, не все ваши ответы работают.Давайте подготовим тестовую среду:
CREATE TABLE `order_history` (
`id_order_history` int(11) NOT NULL AUTO_INCREMENT,
`id_order` int(11) NOT NULL,
`id_order_state` int(11) NOT NULL,
`date_add` datetime NOT NULL,
PRIMARY KEY (`id_order_history`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin2;
CREATE TABLE `orders` (
`id_order` int(11) NOT NULL AUTO_INCREMENT,
`id_customer` int(11) DEFAULT NULL,
PRIMARY KEY (`id_order`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin2;
INSERT INTO `order_history`
(`id_order_history`, `id_order`, `id_order_state`, `date_add`) VALUES
(1,1,1,'2011-01-01 00:00:00'),
(2,1,2,'2011-01-01 00:10:00'),
(3,1,3,'2011-01-01 00:20:00'),
(4,2,1,'2011-02-01 00:00:00'),
(5,2,2,'2011-02-01 00:25:01'),
(6,2,3,'2011-02-01 00:25:59'),
(7,3,1,'2011-03-01 00:00:01'),
(8,3,2,'2011-03-01 00:00:02'),
(9,3,3,'2011-03-01 00:01:00'),
(10,3,2,'2011-03-02 00:00:01');
COMMIT;
INSERT INTO `orders` (`id_order`, `id_customer`) VALUES
(1,1),
(2,2),
(3,3),
(4,4),
(5,5),
(6,6),
(7,7);
COMMIT;
Теперь давайте выберем последнее / максимальное состояние для каждого ордера, поэтому давайте запустим простой запрос:
select id_order, max(date_add) as MaxDate
from `order_history`
group by id_order
это даст нам ПРЕВОСХОДНЫЕ результаты, без ракетостроенияпрямо сейчас:
id_order MaxDate
---------+-------------------
1 2011-01-01 00:20:00 //last order_state=3
2 2011-02-01 00:25:59 //last order_state=3
3 2011-03-02 00:00:01 //last order_state=2
Теперь для простоты, чтобы изменить наши запросы, чтобы получить Заказы , где Последнее состояние не равно 3 .
Мы ожидаем получить один результат строки с id_order = 3 .
Итак, давайте проверим наши запросы:
QUERY 1 от RedFilter :
select oh.id_order, oh.id_order_state, oh.date_add
from (
select id_order, max(date_add) as MaxDate
from `order_history`
where id_order_state not in (3)
group by id_order
) ohm
inner join `order_history` oh on ohm.id_order = oh.id_order
and ohm.MaxDate = oh.date_add
Результат:
id_order id_order_state date_add
-------------------------------------------------
1 2 2011-01-01 00:10:00
2 2 2011-02-01 00:25:01
3 2 2011-03-02 00:00:01
Так что не соответствует действительности
QUERY 2 от Тома Х. :
SELECT DISTINCT OH1.id_order
FROM order_history OH1
LEFT OUTER JOIN order_history OH2 ON
OH2.id_order = OH1.id_order AND
OH2.id_order_state NOT IN (3) AND
OH2.`id_order_history` >= OH1.`id_order_history`
WHERE
OH2.id_order IS NULL
Результат:
id_order
--------
1
2
Так что не соответствует действительности
Любые предложения приветствуются.
РЕДАКТИРОВАТЬ
Благодаря комментарию Андрея М. у нас есть правильное решение .Это модификация запроса Tom H. Все должно выглядеть следующим образом:
SELECT DISTINCT
OH1.id_order
FROM
order_history OH1
LEFT OUTER JOIN order_history OH2 ON
OH2.id_order = OH1.id_order
AND OH2.date_add > OH1.date_add
WHERE OH1.id_order_state NOT IN (3) AND OH2.id_order IS NULL
РЕДАКТИРОВАТЬ 2:
QUERY 3 от DRapp :
select
distinct orders.`id_order`
from
( select oh.id_order,
max( oh.id_order_history ) LastID_HistoryPerOrder
from
order_history oh
group by
oh.id_order ) PreQuery
join order_history oh2
on PreQuery.id_order = oh2.id_order
AND PreQuery.LastID_HistoryPerOrder = oh2.id_order_history
AND NOT oh2.id_order_state IN (1,3)
join orders
on PreQuery.id_order = orders.id_order
Результат:
id_order
--------
3
Итак, наконец-то true