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

Кои СУБД позволяват подреждане по атрибут, който не присъства в клаузата за избор?

Вашата заявка е напълно законен синтаксис, можете да подреждате по колони, които не присъстват в избраното.

Ако имате нужда от пълните спецификации относно законното подреждане, в SQL Standard 2003 той има дълъг списък от изявления за това какво трябва и какво не трябва да съдържа поръчката по (02-Foundation, страница 415, раздел 7.13 <Израз на заявка>, под част 28). Това потвърждава, че вашата заявка е законен синтаксис.

Мисля, че объркването ви може да възникне от избора и/или подреждането по колони, които не присъстват в групата от, или подреждането по колони, които не са в избраното, когато използвате different.

И двете имат един и същ основен проблем и MySQL е единственият, доколкото ми е известно, който позволява и двата.

Проблемът е в това, че когато се използва group by или different, колоните, които не се съдържат в нито една от двете, не са необходими, така че няма значение дали имат множество различни стойности в редовете, защото никога не са необходими. Представете си този прост набор от данни:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |
2   |    A    |    Z     |
3   |    B    |    Y     |

Ако пишете:

SELECT  DISTINCT Column1
FROM    T;

Ще получите

 Column1 
---------
     A   
     B   

Ако след това добавите ORDER BY Column2 , коя от двете колони2 бихте използвали, за да подредите A по, X или Z? Не е детерминистично как да изберете стойност за колона 2.

Същото важи и за избор на колони, които не са в групата от. За да опростите нещата, просто си представете първите два реда от предишната таблица:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |
2   |    A    |    Z     |

В MySQL можете да пишете

SELECT  ID, Column1, Column2
FROM    T
GROUP BY Column1;

Това всъщност нарушава SQL стандарта, но работи в MySQL, но проблемът е, че не е детерминиран, резултатът:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |

Не е повече или по-малко правилно от

ID  | Column1 | Column2  |  
----|---------+----------|
2   |    A    |    Y     |

Така че това, което казвате, е да ми дадете един ред за всяка отделна стойност на Column1 , което и двата набора резултати удовлетворяват, така че как да разберете кой ще получите? Е, не го правите, изглежда е доста популярно погрешно схващане, че можете да добавите и ORDER BY клауза, за да повлияе на резултатите, така че например следната заявка:

SELECT  ID, Column1, Column2
FROM    T
GROUP BY Column1
ORDER BY ID DESC;

Ще гарантира, че ще получите следния резултат:

ID  | Column1 | Column2  |  
----|---------+----------|
2   |    A    |    Y     |

поради ORDER BY ID DESC , обаче това не е вярно (както е показано тук ).

Документите на MySQL състояние:

Така че, въпреки че имате поръчка, това не се прилага, докато не бъде избран един ред от група и този ред не е детермистичен.

SQL-Standard позволява колони в списъка за избор, които не се съдържат в GROUP BY или агрегатна функция, но тези колони трябва да са функционално зависими от колона в GROUP BY. От SQL-2003-Standard (5WD-02-Foundation-2003-09 - страница 346) - http ://www.wiscorp.com/sql_2003_standard.zip

Например, идентификаторът в примерната таблица е ПЪРВИЧНИЯ КЛЮЧ, така че знаем, че е уникален в таблицата, така че следната заявка отговаря на SQL стандарта и ще се изпълнява в MySQL и ще се провали в много СУБД в момента (Към момента на писане на Postgresql е най-близката СУБД, за която познавам, за правилно прилагане на стандарта - Пример тук ):

SELECT  ID, Column1, Column2
FROM    T
GROUP BY ID;

Тъй като ID е уникален за всеки ред, може да има само една стойност на Column1 за всеки идентификатор, една стойност на Column2 няма неяснота какво да се върне за всеки ред.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PHP и MySQL Включително бутон Изтриване на същата страница

  2. docker compose:връзката за пролетно зареждане с базата данни на mysql е отказана

  3. Намиране на разликата между две стойности в една и съща колона в MySQL

  4. Нулирането на AUTO_INCREMENT отнема много време в MySQL

  5. Външен ключ за няколко колони:Задайте една колона на Null ПРИ ИЗТРИВАНЕ вместо всички