Как объединить две таблицы MySQL, сгруппированные в зависимости от значения max () - PullRequest
0 голосов
/ 07 сентября 2011

при реализации встроенной функции поиска для нашего локального файлового архива у меня возникла серьезная проблема, для которой я не нашел ответа. У нас есть две таблицы:

 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

Есть ли возможность сделать это с помощью одного оператора 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

Обе таблицы, имеющие ~ 16 тыс. Строк, для выполнения этого оператора требуется 0,9 секунды, что в 120 раз быстрее, чем первое решение для объединения.

Ответы [ 4 ]

1 голос
/ 08 сентября 2011

Решение (без изменения индексов в моих таблицах):

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

Обе таблицы, имеющие ~ 16 тыс. Строк, для выполнения этого оператора требуется 0,9 секунды, что в 120 раз быстрее, чем первое решение для объединения.

Я знаю, что это не лучшее, что вы можете сделать с SQL

0 голосов
/ 07 сентября 2011

Попробуйте это -

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 голосов
/ 07 сентября 2011

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
)

надеюсь, что это может помочь.

0 голосов
/ 07 сентября 2011

Попробуйте это (я назвал ваши таблицы table1 и table2):

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
...