2013-08-17 33 views
1

我一直在試圖找出這一個很長一段時間,但我開始放棄。ORDER BY和極限1在加入表

爲了簡化情況,假設我有兩個表格。主表是articles,我還要加入contracts。合約表具有結束日期。 我只想從這裏從每篇文章中挑選一(1)行,選擇最新的contract_to日期。

我試過試過類似LEFT JOIN contracts ON (contracts.article = articles.id) ORDER BY contract_to DESC LIMIT 1但顯然它不工作。

我該如何去做這件事?

請假裝下面合同表中每一行的日期範圍是不同的。
此外,所有文章合約的最新日期都不相同,所以我不能確定最新日期,然後將其粘貼到WHERE子句中。

enter image description here

回答

3

要獲得最新contract_to值,你需要一個MAX()聚集。執行此操作的正確方法是使用子查詢連接來僅獲取articleMAX(contract_to)值,然後將其與該行的其餘值進行連接。最後,整個結構可以連接到articles表。

SELECT 
    articles.*, 
    contracts.* 
FROM 
    articles 
    /* Join against a subquery which returns only the article and latest contract_to */ 
    LEFT JOIN (
    SELECT article, MAX(contract_to) AS contract_to 
    FROM contracts 
    GROUP BY article 
) maxcontract ON articles.article_id = maxcontract.article 
    /* and join that against the rest of the contracts table, on those two column values */ 
    JOIN contracts 
    ON maxcontract.article = contracts.article 
    AND maxcontract.contract_to = contracts.contract_to 

由於MySQL是寬鬆有關GROUP BY條款的內容,這種方法實際上可能沒有必要,對contracts表單獨加入,並且你很可能與子查詢獨自做到這一點加入,但贏得」在大多數其他關係型數據庫管理系統中工作並且這是真正正確的方式,而不依賴於MySQL的怪異行爲。

+0

嘗試了這一點,並得到錯誤,「ON子句中的未知列'maxcontract.article'」。別名不起作用了嗎? – silkfire

+0

@silkfire我有一個'maxcontracts'而不是'maxcontract' –

+0

我在合約表中有16366行。我得到的結果是大約6000行。有什麼不對......目前我只有每篇文章和地區有一個日期(是的,這是一個額外的維度),但我將來會有更多。 – silkfire

1

MySQL不具備很好的分析功能,一些的DBMS提供了這一點,但你可以寫(例如):

SELECT ... 
    FROM articles 
    LEFT 
OUTER 
    JOIN (SELECT article, 
       MAX(contract_to) AS contract_to 
      FROM contracts 
      GROUP 
      BY article 
     ) articles_to_max_contracts 
    ON articles_to_max_contracts.article = articles.id 
    LEFT 
OUTER 
    JOIN contracts 
    ON contracts.article = articles.id 
    AND contracts.contract_to = articles_to_max_contracts.contract_to 
; 
0

得到公正的價格,你也可以用相關做到這一點子查詢:

select a.*, 
     (select price 
     from contracts c 
     where a.article = c.article 
     order by contract_from desc 
     limit 1 
     ) as lastPrice 
from articles a; 

隨着contracts(article, contract_from)這一變化的指數,甚至應該是比較有效的。

+0

剛剛嘗試過,查詢花費了12秒,當它通常需要0.3秒(這也很慢)。 – silkfire

+0

@silkfire。 。 。這是與索引? –

+0

這就是索引,是= / – silkfire