![](/img/trans.png)
[英]Filter orders that have a mismatch with order state with the last order state in order history
[英]Select last Order state from Orders
我有桌子:
命令:
id_order id_customer
1 1
2 2
3 1
orders_history
id_history id_order id_order_state date_add
1 1 1 2010-01-01 00:00:00
2 1 2 2010-01-02 00:00:00
3 1 3 2010-01-03 00:00:00
4 2 2 2010-05-01 00:00:00
5 2 3 2011-05-02 00:00:00
6 3 1 2011-05-03 00:00:00
7 3 2 2011-06-01 00:00:00
order_state
id_order_state name
1 New
2 Sent
3 Rejected
4 ...
如何获得所有order_id,其中该订单的最后id_order_state(最后,我的意思是说MAX(id_history)或MAX(date_add))不等于1或3?
select oh.id_history, oh.id_order, oh.id_order_state, oh.date_add
from (
select id_order, max(date_add) as MaxDate
from orders_history
where id_order_state not in (1, 3)
group by id_order
) ohm
inner join orders_history oh on ohm.id_order = oh.id_order
and ohm.MaxDate = oh.date_add
另一个可能的解决方案:
SELECT DISTINCT
id_order
FROM
Orders_History OH1
LEFT OUTER JOIN Orders_History OH2 ON
OH2.id_order = OH1.id_order AND
OH2.is_order_state IN (1, 3) AND
OH2.date_add >= OH1.date_add
WHERE
OH2.id_order IS NULL
我认为他所追求的是完成的订单……即订单的最终状态,而不是那些专门排除1和3的订单。 无论状态码如何,第一个预查询都应为最大ID
select
orders.*
from
( select oh.id_order,
max( oh.id_history ) LastID_HistoryPerOrder
from
orders_history oh
group by
oh.id_order ) PreQuery
join orders_history oh2
on PreQuery.ID_Order = oh2.id_order
AND PreQuery.LastID_HistoryPerOrder = oh2.id_history
AND NOT OH2.id_order_state IN (1, 3) <<== THIS ELIMINATES 1's & 3's from result set
join Orders <<= NOW, anything left after above ^ is joined to orders
on PreQuery.ID_Order = Orders.ID_Order
只是为了重新显示您的数据...我已按ORDER标记了最后一个SEQUENCE(ID_History)...这就是PREQUERY将要返回的内容...
id_history id_order id_order_state date_add
1 1 1 2010-01-01 00:00:00
2 1 2 2010-01-02 00:00:00
**3 1 3 2010-01-03 00:00:00
4 2 2 2010-05-01 00:00:00
**5 2 3 2011-05-02 00:00:00
6 3 1 2011-05-03 00:00:00
**7 3 2 2011-06-01 00:00:00
“ PreQuery”将包含以下子集
ID_Order LastID_HistoryPerOrder (ID_History)
1 3 (state=3) THIS ONE WILL BE SKIPPED IN FINAL RESULT
2 5 (state=3) THIS ONE WILL BE SKIPPED IN FINAL RESULT
3 7 (state=2)
现在,将其结果重新结合回到这两个元素上的订购历史记录中……却添加了排除“订购状态”的1,3条目的条件。
在这种情况下,
1 would be rejected as its state = 3 (sequence #3),
2 would be rejected since its last history is state = 3 (sequence #5).
3 would be INCLUDED since its state = 2 (sequence #7)
最后,所有加入订单的结果都将具有一个ID,并且仅与Order_ID上的orders表匹配就可以得到所需的结果。
我之所以使用“我的问题的答案”,是因为我需要发布您查询的结果。 所以。
不幸的是,并非您的所有回答都能奏效。 让我们准备测试环境:
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
现在为简单起见,以免更改查询以获取Last State不等于3的 Orders。
我们期望获得id_order = 3的一行结果 。
因此,让我们测试一下我们的查询:
通过RedFilter作出查询1:
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
所以那不是真的
Tom H.提出的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
所以那不是真的
任何建议表示赞赏。
编辑
感谢Andriy M.评论,我们有适当的解决方案 。 它是对Tom H的修改。query的所有外观如下:
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:
DRapp制作的QUERY 3:
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
所以这是真的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.