2011-12-05 176 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