În acest puzzle, vom învăța cum să rescriem o subinterogare folosind îmbinări interioare. Cunoașterea unui subquery versus inner join vă poate ajuta la întrebările de la interviu și la problemele de performanță. Deși subinterogările au abilități unice, există momente în care este mai bine să folosiți alte construcții SQL, cum ar fi join-urile.
Lecturând acest articol veți învăța despre mai multe tipuri de subinterogări și despre cum fiecare dintre ele poate fi schimbată într-o altă formă, cum ar fi un join.
Rezolvarea puzzle-urilor este o modalitate excelentă de a învăța SQL. Nimic nu se compară cu exersarea a ceea ce ați învățat. După ce ați rezolvat puzzle-ul, postați răspunsul dvs. în comentarii, astfel încât să putem învăța cu toții unii de la alții. De asemenea, discutăm despre puzzle și multe altele în Essential SQL Learning Group pe Facebook. Asigurați-vă că ne găsiți acolo!
Întrebare de puzzle SQL
Un remediu pentru confuzia interogărilor…
Un coleg de serviciu tocmai a învățat despre subinterogări și a scris niște SQL pentru a prelua numele angajaților și datele de naștere din baza de date AdventureWorks. Problema este că vrea să-l modifice și acum este greu de citit!
Puteți să-l ajutați să simplifice următorul SQL?
SELECT E.HireDate, (SELECT FirstName FROM Person.Person P1 WHERE P1.BusinessEntityID = E.BusinessEntityID), (SELECT LastName FROM Person.Person P2 WHERE P2.BusinessEntityID = E.BusinessEntityID), E.BirthDateFROM HumanResources.Employee EWHERE (SELECT PersonType FROM Person.Person T WHERE T.BusinessEntityID = E.BusinessEntityID) = 'EM'ORDER BY HireDate, (SELECT FirstName FROM Person.Person P1 WHERE P1.BusinessEntityID = E.BusinessEntityID)
Ce declarație ați scrie pentru a-l face mai ușor de citit și, poate, să ruleze mai eficient?
Subquery versus Inner Join Răspuns
Înainte de a începe să vorbim despre interogarea existentă… ce este aceasta?
Vă veți vedea că interogarea combină date din două tabele diferite. Aceasta face acest lucru folosind subinterogări în ambele clauze FROM și WHERE. Acestea sunt evidențiate mai jos în albastru.
SELECT E.HireDate, (SELECT FirstName FROM Person.Person P1 WHERE P1.BusinessEntityID = E.BusinessEntityID), (SELECT LastName FROM Person.Person P2 WHERE P2.BusinessEntityID = E.BusinessEntityID), E.BirthDateFROM HumanResources.Employee EWHERE (SELECT PersonType FROM Person.Person T WHERE T.BusinessEntityID = E.BusinessEntityID) = 'EM'ORDER BY HireDate, (SELECT FirstName FROM Person.Person P1 WHERE P1.BusinessEntityID = E.BusinessEntityID)
De asemenea, vedeți că fiecare clauză WHERE a subinterogării restricționează rândurile returnate la cele egale cu Employee.BusinessEntityID. Aceasta este ceea ce oamenii numesc o subinterogare corelată.
Doresc, de asemenea, să subliniez faptul că interogările din FROM trebuie să returneze o singură valoare (scalară). Dacă nu o fac, atunci se aruncă o eroare.
Așa cum vă puteți imagina, acest lucru este periculos, deoarece poate fi dificil să se garanteze că o interogare returnează cel mult un rând. Știu că am fost în siguranță în acest caz, știu acest lucru deoarece condiția de potrivire are loc între cheile primare ale fiecărei tabele.
Subquery versus Inner Join – Conversia interogării
Dacă aș fi scris această interogare aș fi folosit un INNER JOIN. Iată interogarea pe care aș scrie-o:
SELECT E.HireDate, P.FirstName, P.LastName, E.BirthDateFROM HumanResources.Employee E INNER JOIN Person.Person P ON P.BusinessEntityID = E.BusinessEntityIDWHERE P.PersonType = 'EM'ORDER BY E.HireDate, P.FirstName
Ce este mai ușor de citit?
Aceasta nu ar trebui să fie o mare dezbatere, INNER JOIN este mult mai scurt și cred că la obiect. Clauza join vorbește de la sine. Știți că leagă două tabele între ele; în timp ce, cu subquery, este atât de aparent.
Versiunea INNER JOIN este mai ușor de întreținut.
De asemenea, cu metoda subquery, veți vedea că o mare parte din cod se repetă. Acest lucru poate să nu pară o mare problemă, acum, dar dacă va trebui vreodată să schimbați interogarea, este, deoarece acum, când faceți o modificare, trebuie să vă asigurați că faceți aceeași modificare în mai multe locuri.
SubQuery sau Inner Join? Which is More Efficient?
Iată planul de interogare pentru versiunea cu subinterogare:
Am evidențiat efectul celor patru subinterogări. Pentru această declarație, fiecare interogare are ca rezultat o buclă imbricata. Acestea nu sunt bune.
Înseamnă că, dacă aveți zece rânduri în două tabele fiecare, atunci trebuie, în medie, să iterați prin al doilea tabel de 50 de ori (100/2) pentru fiecare rând din primul pentru a găsi o potrivire. Acest lucru înseamnă că, în loc ca o căutare să dureze două sau trei operații pentru a găsi o potrivire, potrivirea ar putea dura până la 100 * 50 = 500 de căutări pentru a o găsi.
Buclele imbricate sunt o realitate a vieții, dar mai puțin este mai bine.
Și iată versiunea pentru INNER JOIN:
SET SHOWPLAN_ALL ONSELECT E.HireDate, P.FirstName, P.LastName, E.BirthDateFROM HumanResources.Employee E INNER JOIN Person.Person P ON P.BusinessEntityID = E.BusinessEntityIDWHERE P.PersonType = 'EM'ORDER BY E.HireDate, P.FirstName
Aici vedeți că există doar o singură buclă imbricata. Cu siguranță că este mai bine decât patru.
După observarea atât a SQL-ului cât și a planurilor de interogare pentru fiecare set de declarații, puteți vedea că INNER JOIN este superior din mai multe puncte de vedere; cu toate acestea, uitați-vă la acest plan simplificat!
Adevărata sarcină a interogării este de a combina coloane din două tabele; la acest lucru excelează INNER JOIN. Sigur, există momente în care subinterogările au sens și pot fi folosite pentru a face lucruri pe care nu le puteți face cu join-uri, dar în acest caz, nu are sens să folosiți una.