2011-09-07 37 views
0

,同時爲我們的本地文件存檔實施內嵌搜索功能我已經想出了一個嚴重的問題,我找不到答案。我們有兩個表:如何根據max()值加入兩個MySQL表格

 
fild_id | file_name 
--------------------- 
     1 | this_file 
     2 | that_file 
     3 | new_file 

file_archive_id | file_archive_version | file_id 
-------------------------------------------------- 
       1 |     1 |  1 
       2 |     2 |  1 
       3 |     1 |  2 
       4 |     1 |  3 
       5 |     3 |  1 

我想加入通過file_id的兩個表,只選擇一個file_archive一行最大的file_archive_version:

 
fild_id | file_name | file_archive_id | file_archive_version 
-------------------------------------------------------------- 
     1 | this_file |    5 |     3 
     2 | that_file |    3 |     1 
     3 | new_file |    4 |     1 

是否有可能通過一個單一的選擇要做到這一點聲明?

解決方案:具有〜16K行

 
SELECT df.*, 
     (
     SELECT dfa.file_archive_id 
      FROM dca_file_archive dfa 
      WHERE df.file_id = dfa.file_id 
      ORDER BY dfa.file_archive_version desc LIMIT 1 
     ) as file_archive_id, 
     (
     SELECT dfa.file_archive_version 
      FROM dca_file_archive dfa 
      WHERE df.file_id = dfa.file_id 
      ORDER BY dfa.file_archive_version desc LIMIT 1 
     ) as file_archive_version 
FROM dca_file df 

這兩個表,該語句採用0.9秒執行,這比第一溶液加入120X更快。

+0

重複的http://stackoverflow.com/questions/2181043/mysql-like-a-join-but-only-need-the-newest -row –

+0

不重複。這一個更復雜,因爲整行是想要的,而不僅僅是MAX() - 值... –

+0

它只是部分重複,但因爲我剛剛得知可以用select語句替代一個新列,我可以只需加倍額外的選擇語句,這比其他版本快得多。 不過,這不是有史以來最快的(; – mo0h

回答

1

解決方案(在不改變我的表的索引):

 
SELECT df.*, 
     (
     SELECT dfa.file_archive_id 
      FROM dca_file_archive dfa 
      WHERE df.file_id = dfa.file_id 
      ORDER BY dfa.file_archive_version desc LIMIT 1 
     ) as file_archive_id, 
     (
     SELECT dfa.file_archive_version 
      FROM dca_file_archive dfa 
      WHERE df.file_id = dfa.file_id 
      ORDER BY dfa.file_archive_version desc LIMIT 1 
     ) as file_archive_version 
FROM dca_file df 

具有16K〜行這兩個表,這句話需要0.9秒來執行,這比第一個連接解決方​​案快120倍。

我知道這是不是最好的,你可以用SQL做

0

試一下這個(我命名你的表table1table2):

SELECT 
    t1.fild_id, 
    t1.file_name, 
    t2A.file_archive_id, 
    t2A.file_archive_version 
FROM 
    table1 t1 
JOIN 
    table2 t2A ON (t1.fild_id = t2A.file_id) 
WHERE 
    NOT EXISTS (
     SELECT 
      * 
     FROM 
      table2 t2B 
     WHERE 
      t2A.file_id = t2B.file_id 
     AND 
      t2B.file_archive_id > t2A.file_archive_id 
    ) 
ORDER BY t1.fild_id 
+0

這個工作,非常感謝,但它殺死了我的服務器。從字面上看,每個表有16k行,這個語句會阻塞每個輸入10分鐘;) – mo0h

+0

You sho請檢查您的索引。嘗試在查詢之前放置EXPLAIN以查看MySQL的執行計劃。 –

+0

可悲的是,目前沒有辦法改變任何表格索引,所以我必須處理已經存在的內容。 – mo0h

0

嘗試這一個 -

SELECT f.*, a1.file_archive_id, a1.file_archive_version FROM files f 
JOIN file_archives a1 
    ON f.file_id = a1.file_id 
JOIN (
    SELECT file_id, MAX(file_archive_version) max_file_archive_version FROM file_archives GROUP BY file_id 
) a2 
    ON a1.file_id = a2.file_id AND a1.file_archive_version = a2.max_file_archive_version; 
+0

該聲明也起作用,它殺死我的服務器比第一個稍微少一點。不過,每個16k行,這一個需要大約2分鐘執行。 – mo0h

+0

關係中使用的字段應該編入索引。 – Devart

+0

不幸的是,目前沒有辦法改變任何表格索引,所以我必須要處理已經存在的內容。 – mo0h

0

T1作爲第一個表,
T2作爲第二臺

SELECT t1.file_id as tx_id,t1.file_name,tx.file_archive_id,tx.file_archive_version 
FROM maindb.t1 t1,maindb.t2 tx 
WHERE t1.file_id = tx.file_id 
GROUP BY t1.file_id 
HAVING max(tx.file_archive_version) >= all (
    SELECT max(t2.file_archive_version) 
    FROM maindb.t2 
    WHERE t2.file_id = tx_id 
) 

希望它可以幫助。