sql >> Database >  >> RDS >> Mysql

Welke DBMS's laten een volgorde toe van een attribuut dat niet aanwezig is in de select-clausule?

Uw zoekopdracht is volkomen legale syntaxis, u kunt sorteren op kolommen die niet aanwezig zijn in de selectie.

Als u de volledige specificaties over juridische volgorde nodig hebt, heeft de SQL Standard 2003 een lange lijst met uitspraken over wat de volgorde door wel en niet zou moeten bevatten, (02-Foundation, pagina 415, sectie 7.13 , sub deel 28). Dit bevestigt dat uw zoekopdracht een juridische syntaxis is.

Ik denk dat uw verwarring zou kunnen ontstaan ​​door het selecteren en/of bestellen op kolommen die niet in de groep voorkomen op, of bestellen op kolommen die niet in de selectie staan ​​wanneer u onderscheidend gebruikt.

Beiden hebben hetzelfde fundamentele probleem, en MySQL is de enige bij mijn weten die beide toelaat.

Het probleem is dat bij het gebruik van group by of distinct kolommen die niet in een van beide voorkomen, niet nodig zijn, dus het maakt niet uit of ze meerdere verschillende waarden in rijen hebben, omdat ze nooit nodig zijn. Stel je deze eenvoudige dataset voor:

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

Als je schrijft:

SELECT  DISTINCT Column1
FROM    T;

Je zou krijgen

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

Als u vervolgens ORDER BY Column2 . toevoegt , welke van de twee kolom2's zou je gebruiken om A te ordenen op, X of Z? Het is niet bepalend voor het kiezen van een waarde voor kolom2.

Hetzelfde geldt voor het selecteren van kolommen die niet in de groep op staan. Om de zaken te vereenvoudigen, stelt u zich de eerste twee rijen van de vorige tabel eens voor:

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

In MySQL kun je schrijven

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

Dit breekt eigenlijk de SQL-standaard, maar het werkt in MySQL, maar het probleem is dat het niet-deterministisch is, het resultaat:

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

Is niet meer of minder correct dan

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

Dus wat je zegt is geef me een rij voor elke afzonderlijke waarde van Column1 , waaraan beide resultatenreeksen voldoen, dus hoe weet u welke u krijgt? Nou, dat doe je niet, het lijkt een vrij populaire misvatting te zijn die je kunt toevoegen en ORDER BY clausule om de resultaten te beïnvloeden, dus bijvoorbeeld de volgende vraag:

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

Zou ervoor zorgen dat u het volgende resultaat krijgt:

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

vanwege de ORDER BY ID DESC , maar dit is niet waar (zoals hier aangetoond ).

De MySQL-documenten staat:

Dus ook al heb je een bestelling, deze is pas van toepassing nadat één rij per groep is geselecteerd, en deze ene rij is niet bepalend.

De SQL-standaard staat wel kolommen toe in de selectielijst die niet in de GROUP BY of een aggregatiefunctie voorkomen, maar deze kolommen moeten functioneel afhankelijk zijn van een kolom in de GROUP BY. Van de SQL-2003-Standard (5WD-02-Foundation-2003-09 - pagina 346) - http ://www.wiscorp.com/sql_2003_standard.zip

ID in de voorbeeldtabel is bijvoorbeeld de PRIMARY KEY, dus we weten dat deze uniek is in de tabel, dus de volgende query voldoet aan de SQL-standaard en zou in MySQL worden uitgevoerd en momenteel in veel DBMS mislukken (op het moment van schrijven van Postgresql is het DBMS dat ik ken om de standaard correct te implementeren - Voorbeeld hier ):

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

Aangezien ID uniek is voor elke rij, kan er slechts één waarde zijn van Column1 voor elke ID, één waarde van Column2 er is geen onduidelijkheid over wat voor elke rij moet worden geretourneerd.



  1. PHPmailer - Meerdere e-mails versturen

  2. $this->db->insert_id() werkt niet in mysql codeigniter

  3. Creditcardnummers opslaan in SESSION - manieren om het te omzeilen?

  4. Prestatieverschillen tussen gelijk (=) en IN met één letterlijke waarde