Вы действительно используете пресловутую нестандартную реализацию MySQL GROUP BY
.Прочитайте это для получения дополнительной информации https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html
Ваш запрос эквивалентен с использованием ANY_VALUE()
для значений из второй таблицы, например:
SELECT su.id, su.name,
ANY_VALUE(sua.line_1) line_1,
ANY_VALUE(sua.line_2) line_2
FROM site_user su
JOIN site_user_address sua
ON sua.user_id = su.id
WHERE su.id = 1
GROUP BY su.id
КакПока site_user.id уникален для каждой строки, вы получите правильное имя, потому что оно зависит от значения id.
Но для значений из другой таблицы ваши результаты будут, формально говоря, недетерминированными или непредсказуемыми .Они возвращаются из одного ряда друг с другом?Непредсказуемый.
Непредсказуемый, как случайный, но хуже.Случайный подразумевает, что вы иногда будете получать разные значения, так что вы можете поймать проблемы в тесте.Непредсказуемый означает, что вы будете получать одни и те же значения каждый раз, до тех пор, пока вы этого не сделаете. Обычно изменения в выбранных значениях происходят, когда таблицы и индексы увеличиваются.
Возможно, вы захотите использоватьзапрос, который дает предсказуемые результаты.Например, этот вернет строки site_user_address
, которые имеют наибольшее значение site_user_address.id
.
SELECT su.id, su.name,
sua.line_1, sua.line_2
FROM site_user su
JOIN (
SELECT MAX(id) id, user_id
FROM site_user_address
GROUP BY user_id
) sumax ON su.id = sumax.user_id
JOIN site_user_address sua ON sumax.id = sua.id
WHERE su.id = 1
Подзапрос:
SELECT MAX(id) id, user_id
FROM site_user_address
GROUP BY user_id
возвращает наибольшее значение site_user_address.id
значение для каждого user_id
значения.Затем вы можете присоединиться к таблице site_user_address, чтобы получить подробные значения для этих id
значений.
Остерегайтесь соблазна сделать вывод, что поведение спроектировано в СУБД, но не документировано, простопотому что вы наблюдаете их.Поведение в вашем вопросе задокументировано .В документации говорится, что это недетерминированный. Это означает, что планировщик запросов СУБД может удовлетворить ваш запрос любым удобным для вас способом.По мере роста таблиц и индексов планировщик запросов может выбирать и делает разные способы удовлетворения одного и того же запроса.Различные планы запросов также могут поступать из разных частей таблиц, находящихся в кэшах.И т. Д. И т. Д.
Эта непредсказуемость трудна для программистов.Мы не допустим непредсказуемости в процедурном коде Java или php.Но SQL декларативен, и многие тысячи программистов годами занимались быстрым выполнением запросов.Не пытайтесь перехитрить СУБД, даже если вы Майкл Стоунбрейкер сам.