MySQL: выберите строки, имеющие максимальное значение для одного поля, и сохраните правильные значения для объединения таблиц - PullRequest
0 голосов
/ 14 октября 2019

Я знаю, что на этот вопрос уже есть много ответов, но я потратил несколько дней, чтобы адаптировать ответы к своему делу, и мне не удается заставить его работать. Поэтому, пожалуйста, будьте добры и помогите мне.

Я делаю этот запрос:

SELECT
    a.id,
    a.commit,
    b.id,
    c.value

FROM TableA a

INNER JOIN TableC c ON c.id_a = a.id
INNER JOIN TableB ON c.id_b = b.id
INNER JOIN TableD d ON a.id_d = d.id

WHERE a.commit <= 9000 AND a.id_s = 10 AND d.id_f = 1

ORDER BY b.custom_order, a.commit ASC

Ниже приведены результаты этого запроса. Я хочу получить только строки, которые имеют наибольший коммит для каждого b.id :

a.id | a.commit | b.id | c.value
--------------------------------
257  | 4000     | 11   | 33
258  | 6000     | 11   | 34
259  | 8000     | 11   | 35
257  | 4000     | 1    | 40
258  | 6000     | 1    | 40
259  | 8000     | 1    | 40
257  | 4000     | 2    | 40
258  | 6000     | 2    | 40
259  | 8000     | 2    | 40
257  | 4000     | 3    | 15
258  | 6000     | 3    | 25
259  | 8000     | 3    | 25

Итак, я хочу, чтобы все строки с коммитом = 8000:

a.id | a.commit | b.id | c.value
--------------------------------
259  | 8000     | 11   | 35
259  | 8000     | 1    | 40
259  | 8000     | 2    | 40
259  | 8000     | 3    | 25

Я нашел это решение ниже, но не могу использовать его с Symfony 3.4 и Doctrine, потому что Doctrine не может выполнить внутреннее соединение подзапроса ...

SELECT
    a1.id,
    a1.commit,
    b1.id,
    c1.value

FROM TableA a1

INNER JOIN TableC c1 ON c1.id_a = a1.id
INNER JOIN TableB ON c1.id_b = b1.id
INNER JOIN TableD d1 ON a1.id_d = d1.id

INNER JOIN(
    SELECT
        b.id,
        MAX(a.commit) max_commit

    FROM TableA a

    INNER JOIN TableC c ON c.id_a = a.id
    INNER JOIN TableB ON c.id_b = b.id
    INNER JOIN TableD d ON a.id_d = d.id

    WHERE a.id_s = 10 AND a.commit <= 9000 AND d.id_f = 1

    GROUP BY b.id

) results ON b1.id = results.id AND a1.commit = results.max_commit

WHERE a1.id_s = 10

ORDER BY b1.custom_order ASC

1 Ответ

0 голосов
/ 14 октября 2019

Я не знаю о Doctrine, но вы можете использовать оконную функцию ROW_NUMBER(), чтобы отфильтровать ненужные вам строки. Например:

SELECT
  a_id,
  commit,
  b_id,
  value
from (
  SELECT
    a.id as "a_id",
    a.commit,
    b.id as "b_id",
    c.value,
    b.custom_order,
    row_number() over(PARTITION BY b.id ORDER BY a.commit DESC) as rn
  FROM TableA a
  INNER JOIN TableC c ON c.id_a = a.id
  INNER JOIN TableB ON c.id_b = b.id
  INNER JOIN TableD d ON a.id_d = d.id
  WHERE a.commit <= 9000 AND a.id_s = 10 AND d.id_f = 1
) x
ORDER BY custom_order, commit ASC
WHERE rn = 1
...