2011-05-16 94 views
2

我有表:从订单选择最后的订单状态

订单:

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?

+0

您可以发布所需的输出吗? – 2011-05-16 18:06:46

回答

1

我想他是后就是订单完成...即他们的最终地位,而不是那些独特的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 

只是为了重新展现你的数据...我已经标明每个订单的最后一个序列(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) 

,这样做的结果,然后重新加入回订购的只是历史这两个要素...但添加条件EXCLUDE“订单状态”的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上的订单表单独匹配,并得到想要的结果。

+0

@DRAP但是对于id_order = 2它应该返回3作为最后的id_order_state。对于id_order = 3,它应该返回2. – Dariusz 2011-05-16 20:43:03

+0

@dario,请重新检查此答案。我已更改预查询结果列名称以帮助澄清我最初从“LastSequence”中所表达的含义。它现在是“LastID_HistoryPerOrder”。另外,在最后的查询中,我有两个应该被删除的<< ==注释行。这些是为了澄清当1和3被删除时。 – DRapp 2011-05-16 21:23:49

+0

@DRapp请查看我的文章,查看您的查理结果。 – Dariusz 2011-05-17 10:28:34

4
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 
+2

作为参考,这类问题通常被称为“分组最大”问题。 – TehShrike 2011-05-16 18:35:22

+0

@TehShrike奇怪,但我没有得到正确的结果:我认为,有MAX日期的问题。与@Tom H.答案一样。 – Dariusz 2011-05-16 18:48:20

+0

@dario'date_add'列的数据类型是什么? – RedFilter 2011-05-16 18:53:20

1

另一种可能的解决方案:

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 
+0

例如设置有:date_add:2011-05-11 22:36:20和2011-04-16 23:21:24它给了我第二个作为最大日期,然后错了id_state – Dariusz 2011-05-16 20:41:04

+1

我不知道你的意思是什么,但如果你试图用LEFT JOIN方法找到极值,那么我认为你有点不对。它应该是...... ON OH2.id_order = OH1.id_order AND OH2.date_add> OH1.date_add WHERE OH1.is_order_state NOT IN(1,3)AND OH2.id_order IS NULL'。 – 2011-05-16 22:17:32

+0

@ andriy -m你有权!@ Tom-h请纠正你的答案,就像andriy-m说的那样,它会完成:) – Dariusz 2011-05-17 11:08:01

0

我使用“回答我的问题”,因为我需要发布您的查询结果。所以。

不幸的是,并非所有的答案球员的作品。让我们准备测试环境:

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

那么让我们来测试我们的查询:

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 

结果:通过RedFilter取得

查询1

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 

所以它不是真的

查询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 

结果:通过汤姆H.取得

id_order 
-------- 
1 
2 

所以它的赞赏不是真的

任何建议。

编辑

感谢舍甫琴科M.评论我们有妥善解决。这是汤姆·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 

因此它是f inally true