sql >> Database teknologi >  >> RDS >> Mysql

Hvilke DBMS'er tillader en rækkefølge af en attribut, som ikke er til stede i select-klausulen?

Din forespørgsel er fuldkommen lovlig syntaks, du kan sortere efter kolonner, der ikke er til stede i valget.

Hvis du har brug for de fulde specifikationer om juridisk bestilling, har den i SQL Standard 2003 en lang liste af udsagn om, hvad rækkefølgen af ​​bør og ikke bør indeholde, (02-Foundation, side 415, afsnit 7.13 , sub del 28). Dette bekræfter, at din forespørgsel er lovlig syntaks.

Jeg tror, ​​at din forvirring kan opstå ved at vælge og/eller sortere efter kolonner, der ikke er til stede i gruppen, eller sortere efter kolonner, der ikke er i udvalg, når du bruger distinkt.

Begge har det samme grundlæggende problem, og MySQL er den eneste, så vidt jeg ved, der tillader enten.

Problemet er dette, at når du bruger gruppe efter eller adskilt, er der ikke behov for kolonner, der ikke er indeholdt i nogen af ​​dem, så det er ligegyldigt, om de har flere forskellige værdier på tværs af rækker, fordi de aldrig er nødvendige. Forestil dig dette simple datasæt:

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

Hvis du skriver:

SELECT  DISTINCT Column1
FROM    T;
 

Du ville få

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

Hvis du derefter tilføjer ORDER BY Column2 , hvilken af ​​de to kolonne2'er ville du bruge til at bestille A efter, X eller Z? Det er ikke deterministisk, hvordan man vælger en værdi for kolonne 2.

Det samme gælder for valg af kolonner, der ikke er i gruppen efter. For at forenkle tingene skal du bare forestille dig de to første rækker i den foregående tabel:

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

I MySQL kan du skrive

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

Dette bryder faktisk SQL-standarden, men det virker i MySQL, men problemet er, at det er ikke-deterministisk, resultatet:

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

Er hverken mere eller mindre korrekt end

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

Så det, du siger, er giv mig en række for hver særskilt værdi af Column1 , som begge resultatsæt opfylder, så hvordan ved du, hvilken du får? Nå det gør du ikke, det ser ud til at være en ret populær misforståelse, at du kan tilføje og ORDER BY klausul for at påvirke resultaterne, så for eksempel følgende forespørgsel:

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

Ville sikre, at du får følgende resultat:

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

på grund af ORDER BY ID DESC , men dette er ikke sandt (som vist her ).

MySQL-dokumenterne angiv:

Så selvom du har en ordre, gælder dette ikke før efter en række pr. gruppe er valgt, og denne ene række er ikke-deterministisk.

SQL-standarden tillader kolonner i valglisten, der ikke er indeholdt i GROUP BY eller en aggregeret funktion, men disse kolonner skal være funktionelt afhængige af en kolonne i GROUP BY. Fra SQL-2003-Standard (5WD-02-Foundation-2003-09 - side 346) - http ://www.wiscorp.com/sql_2003_standard.zip

For eksempel er ID i eksempeltabellen den PRIMÆRE NØGLE, så vi ved, at den er unik i tabellen, så den følgende forespørgsel er i overensstemmelse med SQL-standarden og ville køre i MySQL og fejle i mange DBMS i øjeblikket (På skrivende stund Postgresql er det nærmeste DBMS, jeg kender til korrekt implementering af standarden - Eksempel her ):

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

Da ID er unikt for hver række, kan der kun være én værdi af Column1 for hvert id, én værdi af Column2 der er ingen uklarhed om, hvad der skal returneres for hver række.



  1. Arbejde med MySQL TIMESTAMP-kolonner i SQL Server

  2. Sådan skriver du HQL JOIN-forespørgsel for flere tabels valgte kolonner ved hjælp af Constructor i Select-klausulen

  3. SQLite Undtagen

  4. Forespørg på de sidste N relaterede rækker pr. række