Гарантируется ли произвольно выбранные неагрегированные столбцы из одной строки с MySQL GROUP BY? - PullRequest
0 голосов
/ 28 сентября 2018

Больше интересующего меня вопроса, чем того, что я хочу использовать

Скажем, я запускаю следующий запрос:

  SELECT su.id, su.name, sua.line_1, sua.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 /* id is the PK for site_user */

sua.line_1 и sua.line_2 гарантированно придутвернуться из того же site_user_address ряда?

Я знаю, что, по крайней мере, строка site_user_address выбрана произвольно

Я не смог ничего найти в документации и не могу придумать надежного способачтобы проверить это

ОБНОВЛЕНИЕ

Насколько я знаю, это не дубликат. Мне интересно, произойдет ли произвольный выбор значения изодна и та же произвольно выбранная строка при выборе двух разных столбцов из одной и той же таблицы

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

1 Ответ

0 голосов
/ 28 сентября 2018

Вы действительно используете пресловутую нестандартную реализацию 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 декларативен, и многие тысячи программистов годами занимались быстрым выполнением запросов.Не пытайтесь перехитрить СУБД, даже если вы Майкл Стоунбрейкер сам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...