Ebben a rejtvényben megtanuljuk, hogyan írhatunk át egy alkérdést belső kötésekkel. A subquery versus inner join ismerete segíthet az interjúkérdésekben és a teljesítményt érintő kérdésekben. Bár az alkérdések egyedülálló képességekkel rendelkeznek, vannak olyan esetek, amikor jobb más SQL-konstrukciókat, például a joinokat használni.
A cikk elolvasásával megismerkedhet az alkérdések több típusával, és azzal, hogyan lehet mindegyiket más formára, például joinra váltani.
A rejtvények megoldása remek módja az SQL megtanulásának. Semmi sem jobb, mint a tanultak gyakorlása. Ha megfejtette a rejtvényt, írja meg a választ a hozzászólásokban, hogy mindannyian tanulhassunk egymástól. A Facebookon az Essential SQL Learning Groupban is megbeszéljük a rejtvényt és még sok mást. Keressen minket ott!
SQL rejtvény kérdés
A lekérdezési zűrzavar orvoslása…
Egy munkatársam most tanult meg az alkérdésekről, és írt néhány SQL-t, hogy lekérje az alkalmazottak nevét és születési dátumát az AdventureWorks adatbázisból. A probléma az, hogy meg akarják változtatni, és most már nehezen olvasható!
Segítene nekik egyszerűsíteni a következő SQL-t?
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)
Milyen utasítást írna, hogy könnyebben olvasható legyen, és talán hatékonyabban fusson?
Subquery versus Inner Join Answer
Mielőtt elkezdenénk, beszéljünk a meglévő lekérdezésről… mi is az?
A lekérdezés két különböző táblázat adatait kombinálja. Mindezt a FROM és a WHERE záradékban lévő alkérdések segítségével teszi. Ezek alább kékkel vannak kiemelve.
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)
Azt is láthatja, hogy az egyes alkérdések WHERE záradékai a visszaküldött sorokat az Employee.BusinessEntityID-vel megegyező sorokra korlátozzák. Ezt nevezik korrelált alkérdésnek.
Azt is szeretném kiemelni, hogy a FROM-ban szereplő lekérdezéseknek egyetlen értéket (skalár) kell visszaadniuk. Ha nem ezt teszik, akkor hibát dobnak.
Amint elképzelhető, ez veszélyes, mivel nehéz lehet garantálni, hogy egy lekérdezés legfeljebb egy sort ad vissza. Tudom, hogy biztonságosak voltak ebben az esetben tudom ezt, mivel az egyezés feltétele az egyes táblák elsődleges kulcsai között történik.
Subquery versus Inner Join – A lekérdezés átalakítása
Ha én írnám ezt a lekérdezést, akkor INNER JOIN-t használnék. Íme a lekérdezés, amit írnék:
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
Melyik könnyebben olvasható?
Ez nem lehet nagy vita, az INNER JOIN sokkal rövidebb, és szerintem lényegre törőbb. A join záradék önmagáért beszél. Tudod, hogy két táblát kapcsol össze; míg az al-lekérdezésnél ez annyira nyilvánvaló.
Az INNER JOIN változat könnyebben karbantartható.
Az al-lekérdezéses módszernél ráadásul a kód nagy része ismétlődik. Ez most talán nem tűnik nagy dolognak, de ha valaha is módosítani kell a lekérdezést, akkor az lesz, mivel most, amikor módosítunk, biztosra kell mennünk, hogy ugyanazt a módosítást több helyen is elvégezzük.
SubQuery vagy Inner Join? Melyik a hatékonyabb?
Itt a lekérdezési terv a sub query változathoz:
Kiemeltem a négy subquery hatását. Ennél az utasításnál minden egyes lekérdezés egy egymásba ágyazott hurkot eredményez. Ezek nem jók.
Ez azt jelenti, hogy ha két táblában egyenként tíz sor van, akkor átlagosan 50-szer (100/2) kell végigmennie a második táblán minden egyes sorra az elsőben, hogy találjon egyezést. Ez azt jelenti, hogy ahelyett, hogy egy keresés két vagy három műveletet vesz igénybe az egyezés megtalálásához, az egyezés megtalálása akár 100 * 50 = 500 keresést is igénybe vehet.
A beágyazott ciklusok az élet velejárói, de a kevesebb jobb.
És itt van az INNER JOIN változata:
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
Itt látható, hogy csak egy beágyazott ciklus van. Ez biztosan jobb, mint a négy.
Az SQL és a lekérdezési terveket is megfigyelve mindkét utasításkészlethez láthatjuk, hogy az INNER JOIN több szempontból is jobb; azonban nézzük meg ezt az egyszerűsített tervet!
A lekérdezés valódi feladata két táblázat oszlopainak összekapcsolása; ebben az INNER JOIN kiválóan teljesít. Persze, vannak olyan idők, amikor az allekérdezéseknek van értelme, és olyan dolgokra is használhatók, amikre az egyesítésekkel nem, de ebben az esetben nincs értelme használni egyet sem.