Превратить подзапрос Mysql в соединение - PullRequest
0 голосов
/ 07 апреля 2019

Как мне превратить этот подзапрос в JOIN?

Я прочитал, что подзапросы медленнее, чем JOIN с.

SELECT 
    reklamation.id, 
    reklamation.titel,
    ( 
        SELECT reklamation_status.status 
        FROM reklamation_status 
        WHERE reklamation_status.id_reklamation = reklamation.id 
        ORDER BY reklamation_status.id DESC 
        LIMIT 1 
    ) as status
FROM reklamation 
WHERE reklamation.aktiv=1

Ответы [ 3 ]

0 голосов
/ 07 апреля 2019

Это должно сделать это:

SELECT r.id, r.titel, MAX(s.id) as status
FROM reklamation r
LEFT JOIN reklamation_status s ON s.id_reklamation = r.id
WHERE r.aktiv = 1   
GROUP BY r.id, r.titel

Ключевым моментом здесь является использование агрегация для управления количеством элементов от reklamation до reklamation_status.В исходном коде встроенный подзапрос использует ORDER BY reklamation_status.id DESC LIMIT 1, чтобы вернуть наибольшее значение id в reklamation_status, соответствующее текущему reklamation.Без агрегации мы, вероятно, получили бы несколько записей в наборе результатов для каждого reklamation (по одной для каждого соответствующего reklamation_status).

Еще один момент, который необходимо учитывать, - это тип JOIN.INNER JOIN отфильтровывает записи reklamation с, которые не имеют reklamation_status: исходный запрос со встроенным подзапросом не ведет себя так, поэтому я выбрал LEFT JOIN.Если вы можете гарантировать, что у каждого reklamation есть хотя бы один дочерний элемент в reklamation_status, вы можете безопасно переключиться обратно на INNER JOIN (что может работать более эффективно).


PS:

Я читал, что подзапросы работают медленнее, чем JOIN с.

Это не универсальная истина.Это зависит от многих факторов и не может быть рассмотрено, не видя вашего точного варианта использования.

0 голосов
/ 07 апреля 2019

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

SELECT r.id, r.titel,
       (SELECT rs.status 
        FROM reklamation_status rs
        WHERE rs.id_reklamation = r.id 
        ORDER BY rs.id DESC 
        LIMIT 1 
       ) as status
FROM reklamation  r
WHERE r.aktiv = 1;

Для производительности вы хотите индекс на reklamation_status(id_reklamation, id, status).

Кстати, это тот случай, когда подзапрос, вероятно, самый быстрый методдля выражения этого запроса.Если вы попытаетесь набрать JOIN, вам понадобится некая агрегация, чтобы получить самый последний статус.Это может быть дорого.

0 голосов
/ 07 апреля 2019

Используя JOIN запрос можно переписать в:

SELECT reklamation.id, reklamation.titel, reklamation_status.status
FROM reklamation 
JOIN reklamation_status ON reklamation_status.id_reklamation = reklamation.id
WHERE reklamation.aktiv=1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...