2011-12-05 53 views
0

我有這個慢速查詢一個問題:查詢優化

SELECT c.*, csc1.changed_status 
    FROM contract c 
    LEFT 
    JOIN contract_status_change csc1 
    ON csc1.contract_status_change_id = 
     (SELECT csc2.contract_status_change_id 
      FROM contract_status_change csc2 
      WHERE csc2.contract_id = c.contract_id 
      ORDER 
       BY csc2.date_changed DESC 
      LIMIT 1 
     ) 
; 

我有一個合同表和contract_status_change表,其中記錄狀態違反合同。此查詢加入合同的最新狀態,以便您可以獲得其當前狀態。

請你能幫我整理一下嗎?

-edit-

我的歉意。我已更新查詢以包括選擇實際的最新狀態。對困惑感到抱歉!

+0

[This](http://www.dpriver.com/pp/sqlformat.htm?ref=g_wangz)也許? – Bojangles

+0

選擇 'C'。* 從 ''contract'左C'加入''contract_status_change' ls' 上'ls'.'contract_status_change_id' ='ls'.'contract_status_change_id' 內加入''contract_status_change' SC ' on'c'.'contract_id' ='sc'.'contract_id' order by sc'.'date_changed' desc limit 1 – reggie

回答

1

格式化你的查詢可讀性一致(空格和大寫,去除不必要的反引號和括號,更明智的別名)後:

SELECT c.* 
    FROM contract c 
    LEFT 
    JOIN contract_status_change csc1 
    ON csc1.contract_status_change_id = 
     (SELECT csc2.contract_status_change_id 
      FROM contract_status_change csc2 
      WHERE csc2.contract_id = c.contract_id 
      ORDER 
       BY csc2.date_changed DESC 
      LIMIT 1 
     ) 
; 

,並假設contract_status_change.contract_status_change_id是一個唯一的標識符,我不得不得出結論,您的查詢是等效於此,更有效的一個:

SELECT c.* 
    FROM contract c 
; 

你說,它「是加入對合同的最新狀態,這樣您可以得到它的當前狀態」,但它並不任何與當前狀態—不按順序,不過濾,不包括它在查詢結果—所以沒有這個需要。

+0

從他的描述我認爲你是對的,但也許他想包括csc .date_changed字段在他的選擇中,但在他的問題中省略。 –

0
This should help a bit. 

SELECT c.*, csc1.changed_status 
FROM contract c LEFT JOIN contract_changed_status csc1 ON c.contract_id = csc1.contract_id 
INNER JOIN 
    (
    SELECT contract_id, changed_status, MAX(date_changed) AS 'max_date' 
    FROM contract_status_changed GROUP_BY contract_id 
    GROUP BY contract_id 
    ) csc2 ON csc1.contract_id = csc2.contract_id AND csc1.date_changed = csc2.max_date