Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL нарушава ли стандарта, като позволява избор на колони, които не са част от групата по клауза?

Стандартният SQL ще отхвърли вашата заявка, защото не можете да ИЗБЕРЕТЕ неагрегирани полета които не са част от клаузата GROUP BY в обобщена заявка

Това е вярно, до 1992г .

Но еочевидно погрешно, от 2003 г. и след това.

От стандарт SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, от http ://www.wiscorp.com/ , параграф-7.12 (спецификация на заявката), стр. 398 :

  1. Ако T е групирана таблица, тогава нека G е наборът от групиращи колони на T. Във всяка ((израз на стойност)), съдържаща се в ((изберете списък)), всяка препратка към колона, която препраща към колона от T, ще препраща към някои колона C, която е функционално зависима на Gили се съдържат в обобщен аргумент на ((задаване спецификация на функция)), чиято заявка за агрегиране е QS

Сега MYSQL внедри тази функция, като позволи не само колони, които са функционално зависими на групиращите колонино допускане на всички колони . Това причинява някои проблеми на потребителите, които не разбират как работи групирането и получават неопределени резултати там, където не очакват.

Но имате право да кажете, че MySQL е добавил функция, която противоречи на SQL-стандартите (въпреки че изглежда смятате, че това е по грешна причина). Не е съвсем точно, тъй като са добавили стандартна функция за SQL, но не по най-добрия начин (по-скоро по лесния), но е в противоречие с най-новите стандарти.

За да отговоря на въпроса ви, причината за тази функция на MySQL (разширение) е, че предполагам, че е в съответствие с най-новите SQL-стандарти (2003+). Защо са избрали да го приложат по този начин (не е напълно съвместим), можем само да гадаем.

Както @Quassnoi и @Johan отговориха с примери, това е главно проблем с производителността и поддръжката. Но човек не може лесно да промени RDBMS, за да бъде достатъчно интелигентен (изключен Skynet), за да разпознава функционално зависими колони, така че разработчиците на MySQL направиха избор:

Ние (MySQL) ви предоставяме (потребителите на MySQL) тази функция, която е в стандартите на SQL-2003. Подобрява скоростта в определени GROUP BY запитвания, но има уловка. Трябва да внимавате (а не SQL машината), така че колоните в SELECT и ИМАМ списъците са функционално зависими от GROUP BY колони. Ако не, може да получите неопределени резултати.

Ако искате да го деактивирате, можете да зададете sql_mode до ONLY_FULL_GROUP_BY .

Всичко е в документите на MySQL:Разширения към ГРУПИРАНЕ ПО (5.5) - макар и не в горната формулировка, а като във вашия цитат (дори забравиха да споменат, че това е отклонение от стандартния SQL-2003, докато не е стандартен SQL-92). Този вид избор е често срещан според мен във всеки софтуер, включително други RDBMS. Те са направени за производителност, обратна съвместимост и много други причини. Oracle има известния '' е същото като NULL например и SQL-Server вероятно също има такива.

Има и тази публикация в блога на Peter Bouman, където изборът на MySQL разработчиците се защитава:Развенчаване на ГРУПА ПО митове .

През 2011 г. като @Mark Byers ни информира в коментар (в свързан въпрос в DBA.SE), PostgreSQL 9.1 добави нова функция (дата на пускане:септември 2011 г.), предназначени за тази цел. Той е по-ограничителен от внедряването на MySQL и по-близо до стандарта.

По-късно, през 2015 г. MySQL обяви, че във версия 5.7 поведението е подобрено, за да съответства на стандарта и действително да разпознава функционалните зависимости (дори по-добре от реализацията на Postgres). Документацията:MySQL обработка на GROUP BY (5.7) и друга публикация в блога на Питър Буман:MySQL 5.7.5:GROUP BY зачита функционалните зависимости!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да запишете резултат от MySQL заявка в .CSV файл

  2. mysql_fetch_array() очаква параметър 1 да бъде проблем с ресурсите

  3. Как да разберете кога е стартиран MySQL/MariaDB сървър

  4. PHP PDO срещу нормален mysql_connect

  5. Вмъкване на заявка за вмъкване на редове в MySQL