2011-05-16 398 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