În altă zi, gândit o problemă pe care am dat peste la locul de muncă un an și jumătate în urmă.
La acel moment nu am știut despre sql-ex.ru și cunoștințele mele de SQL au fost destul de slab, la nivelul
Selectați puncte cu join'ami interior simplu. Și îmi amintesc când nu am putut rezolva această problemă, fără
subinterogare suplimentare. Acum, după câteva zeci de probleme rezolvate pe sql-ex.ru I
probleme cu ea stăpânite, care m-au determinat să creadă că este - un test bun pentru cunoaștere
Elementele de bază ale SQL. Spre deosebire de sarcinile mai complexe, această sarcină nu are nevoie de mult timp, dar
Acesta acoperă aproape tot ceea ce este necesar pentru programator mediu de a emite cunoștințe SQL, mai ales dacă vom rezolva în minte. dispar imediat întrebări de genul „Ce este JOIN, LEFT-TE decât diferă de un element interior JOIN, modul în care gruparea“ și așa mai departe.
Astfel, formularea este după cum urmează. Există 2 mese - colectare si Postul.
Este necesar să se facă o selecție
Collection.ID Collection.Name Collection.Count
acele colecții care conțin mai puțin de 5 elemente.
Asta e tot.
Algoritmul pentru rezolvarea problemei.
Ei bine, în mod clar același lucru - este necesar să se facă JOIN, nu JOIN, le grupa de Collection.ID, deriva ID-ul, numele, Count (*).
La naiba. Atunci când gruparea pe ID-ul nu poate fi dedus Nume. Prin urmare, este necesar, fie să-și încheie proba rezultată într-o chiar și o interogare sau adăuga la gruparea numelui. Ok, funcționează. Numai de colectare goală nu este afișată. De ce. Ei bine, în mod clar același lucru - ei nu se încadrează în rezultatul INTERIOARĂ JOIN'a, este necesar să se utilizeze LEFT JOIN. Oh, acum se întoarse. Numai colecția unui martor, și numărul de (*) afișează unitatea în loc de zero. Oh, da, e un LEFT JOIN, el se alătură Collection.ID Collection.Name NULL NULL și numărul (*) dă unității. Cum să rezolvi ceva. Scădeți 1 nu se poate, pentru că puteți șurub sus de colectare astfel încât nu este gol. Noi trebuie să verifice dacă cumva colectarea este gol și de ieșire 0, iar pentru restul - conta (*). Da, avem același drept o NULL, ele pot fi în orice funcție agregată pentru a împinge, și în comparație cu NULL'om. În cazul în care o NULL, atunci o colecție goală, și ieșiri 0, în caz contrar să-l - count (*). Eureka! Ei bine, se adaugă HAVING. Scrie cerere:
SELECT c.ID, c.Name, CASE când numărul (*) = 1 și MAX (i.CollectionID) este nul 0 ELSE conta (*) END din colecția c STÂNGA ÎNSCRIEȚI Postul i PE c.ID = i.CollectionID GROUP PRIN c.ID, c.Name count AVÂND (*) <5