簡體   English   中英

如何連接兩個根據max()值分組的MySQL表

[英]How to join two MySQL tables grouped depending on a max() value

在為我們的本地文件存檔實現內聯搜索功能時,我遇到了一個嚴重的問題,但我沒有找到答案。 我們有兩個表:

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_version的file_archive行:

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

是否有可能通過單個select語句執行此操作?

解:

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倍。

解決方案(不更改表的索引):

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可以做的最好的事情

試試這個(我將您的表命名為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

試試這個-

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;

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
)

希望對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM