2012-07-11 54 views
0

我有很多麻煩轉換一個子查詢,需要將多個值返回到一個內部聯接,由於約束,只有最新版本的最內層的結果應該被返回。我嘗試過搜索和瀏覽各種答案,但找不到修復程序。下面是有點簡化,但顯示了我想要的東西,並沒有在所有的工作:轉換子查詢與訂單+限制1左加入

select 
    works.id as w_id,works.name as w_name,author,publisher, 
    (select name as auth from creators where author=id), 
    (select name as pub from creators where publisher=id), 
    (select version, 
    (select pages,uploaded,uri from info where id=workupdates.info) 
    from workupdates where work=works.id order by date desc limit 1) 
from works 

(信息往往是版本之間不變,但大多數文件都至少有幾),我可以使用多個子查詢,每欄一個,但這是緩慢和愚蠢的。

天真,我把它翻譯成:

select 
    works.id as w_id,works.name as w_name,developer,publisher, 
    (select name as dev from creators where developer=id), 
    (select name as pub from creators where publisher=id), 
    version,pages,uploaded,uri 
from 
    works 
    left join workupdates on workupdates.work = works.id 
    left join info on info.id=workupdates.info 

但很明顯,它返回每個工作,每一個匹配的信息列,多個結果時,我只希望每個工作的最新信息數據。

我看到一個答案,建議像from (select max(date) from workupdates where workupdates.work = works.id) wu inner join works開始,但在我的情況下,只是給了我一個壞的查詢,其中數據庫聲稱works.id不存在。我已經看到並嘗試了很多不同的變體 - 我不知道這麼多類似的查詢可能結構如此不同 - 但我還沒有運氣,我的大腦卻相當疲憊。

回答

0

我認爲,你可以使用worksupdates爲「統治表」,並附上其餘的有:

SELECT works.id, title, version, date, pages, uploaded, uri 
    FROM workupdates 
    JOIN info ON info.id=workupdates.info 
    JOIN works ON workupdates.work = works.id 
    WHERE workupdates.date = 
     (SELECT MAX(date) FROM workupdates WHERE work = works.id) 
; 

即使這是次優的,因爲這些連接將發生在該日期之前過濾。

或周圍旋轉的表和有工作規則,也許更好:

SELECT works.id, title, version, date, pages, uploaded, uri 
    FROM works 
    JOIN workupdates ON (workupdates.work = works.id 
      AND workupdates.date = 
       (SELECT MAX(date) FROM workupdates WHERE work = works.id)) 
    JOIN info ON info.id=workupdates.info 
; 

它應該可以加入worksupdates和作品時節省的迭代器,但它目前還不來找我(和這可能是我在做夢的事情):-(

+0

對我來說簡單和高性能如果我以後遇到瓶頸,我可能會嘗試其他答案,但現在我更喜歡那些更容易掌握和重用的東西。 謝謝! – SilverbackNet 2012-07-12 01:24:54

0

嘗試更換你的第一個LEFT JOIN在你的這一個第二個查詢:

LEFT JOIN 
(
    SELECT aa.* 
    FROM workupdates aa 
    INNER JOIN 
    (
     SELECT work, MAX(date) AS maxdate 
     FROM workupdates 
     GROUP BY work 
    ) bb ON aa.work = bb.work AND aa.date = bb.maxdate 
) b ON works.id = b.work 

這將加入只有最近 workupdates行對每個工作證。