2013-01-11 90 views
0

我現在面臨一個MySQL問題的項目MySQL查詢優化: 我有一個MySQL表至極包含這些列,它的存儲中的每個訂單和訂單的每一個狀態:爲按日期排序與國家

id_order_history/id_employee/id_order/id_order_state/date_add 

我想獲得* id_order *的列表,這些列表在特定的* id_order_state *中 - 比方說10 - 但我不想獲取狀態在這個特定狀態之後改變並且不想收集訂單少於7天...

這是我該如何做到這一點:

首先查詢來獲取訂單列表&日期:

SELECT id_order, date 
      FROM '._DB_PREFIX_.'ps_order_history, 
      WHERE TO_DAYS(NOW()) - TO_DAYS(date_add) <= 7 
      AND id_order_state = 10 

然後循環只得到了令行禁止最新狀態:

$query = ' SELECT id_order, date 
      FROM '._DB_PREFIX_.'ps_order_history, 
      WHERE '; 

foreach ($listAbove, $item) { 
    $query =+ ' 
       ((date > $item['date']) 
       AND (id_order = $item['id'])) 
      '; 
} 
$orderlist = Db::getInstance()->ExecuteS($query); 

這不是真正的優化,我敢肯定,我可以只用一個查詢來做,但不知道如何。

您是否知道如何使這種清潔劑?例如,

回答

2

如果我理解這個權利,那麼您只需要最新狀態等於10的訂單。所以,讓我們通過獲取訂單和最近的狀態

SELECT 
    id_order, 
    MAX(id_order_history) as m 
FROM ps_order_history 
GROUP BY id_order 

這給了我們最新的訂單歷史記錄的項目爲每個訂單開始(假設id_order_history是PK和最大值表示最近的訂單輸入)。現在我們只需在子查詢上查找我們想要的標準。

SELECT 
    poh.id_order 
FROM ps_order_history poh 
INNER JOIN 
(SELECT 
    id_order, 
    MAX(id_order_history) as m 
FROM ps_order_history 
GROUP BY id_order) sub 
ON sub.id_order = poh.id_order 
    AND sub.m = poh.id_order_history 
WHERE poh.id_order_state = 10 
    AND TO_DAYS(NOW()) - TO_DAYS(poh.date_add) <= 7 
+0

這個解決方案看起來不錯,我唯一要改變的地方就是推薦OP將where子句的第二部分改爲AND ANDPh.date_add <= DATE_SUB(DATE(NOW()),INTERVAL 7 DAY )'這將允許在'date_add'字段使用索引,而當前的方法不會。 –

+0

@MikeBrant這是一個很好的建議,那部分肯定需要工作。我認爲簡單的日期扣除可能不會完全達到他想要的效果,但是您可以在7.1天前發佈一些內容,但運行'TO_DAYS'時在技術上仍然在7天內。但是你肯定對索引的使用是正確的 –

+0

如果最終的願望是根據實際的特定日曆日(從午夜開始)顯示'date_add'值,我建議的解決方案就好了,因爲你基本上計算當天的00:00:00(因爲'DATE(NOW())'),並將其用作與'date_add'的比較。對我而言,從邏輯的角度來看,這更清晰。 –

0

您可以在WHERE子句中使用子查詢。這裏有一個例子:

create table order_history 
(orderid int, orderstate int, orderdate date, 
primary key(orderid, orderstate, orderdate)); 

insert into order_history values (1,1,makedate(2012,1)); 
insert into order_history values (1,2,makedate(2012,2)); 
insert into order_history values (1,3,makedate(2012,3)); 
insert into order_history values (2,1,makedate(2012,1)); 
insert into order_history values (2,3,makedate(2012,3)); 
insert into order_history values (3,1,makedate(2012,1)); 

這個查詢現在將選擇其最新的orderstate爲3的所有項目:

select a.orderid, a.orderdate from order_history a 
where a.orderdate = 
    (select max(orderdate) from order_history b where b.orderid = a.orderid) 
and a.orderstate=3 

要通過訂購日期限制,只爲您的日期選擇增加一個條款,到外where條款。