subselect
Kan iemand mij met deze vraag helpen. Ik ben bezig met het leren van sql. De meeste zaken en begrippen begrijp reeds maar subselect lukt niet echt zo vlot. Ik heb onderstaand voorbeeld.
select klantnaam from klant
from klant
where klant_id in
(select klant_id
from uitleen where boek_id in
(select boek_id
from boeken
where jaar= 1993))
Ik begrijp dus dat je de klantnaam oproept van de tabel klant. Ik zie ook dat je een boek_id opvraagt met een jaar uit 1993. En dat je een klant_id zal krijgen uit de tabel uitleen. Maar hoe werkt deze subselect juist. Ik snap de samengang niet zo goed. Wat wordt er juist opgeroepen? Het is om alles beter te begrijpen om zelf subselects toe te passen.
Vanaf hier weet ik het niet meer.
(select klant_id
from uitleen where boek_id in
(select boek_id
from boeken
where jaar= 1993))
Hopelijk kan en wil er iemand mij helpen hiermee?
Alvast bedankt!
Tim
Eerst
Dat levert je een lijst met de id's van alle boeken uit 1993. (laten we zeggen dat dat er 3000 zijn).
Dan de query ervoor:
op de plek van die .... komen dan die 3000 boeken te staan.
Je verkijgt hieruit dus de lijst met alle leners van die boeken.
Tenslotte gaan die id's van de leners dan in de hoofdquery.
Maar
Dat kost je database nogalwat moeite. Die lijsten zijn best groot.
Vaak kun je dat beter met een join doen.
Queries zijn meestal ook vertalingen van informatie (vraagstukken) waar iemand in geinteresseerd is. Deze kun je verwoorden in natuurlijke taal.
Zo bevat je oorspronkelijke query de volgende informatiewens: "Geef mij de namen van klanten die een of meer boeken in bruikleen hebben die in 1993 zijn gepubliceerd".
De query knoopt de eindjes aan elkaar: van klantinformatie naar boekenuitleeninformatie naar boeken.
Je kunt de haakjes in de SQL code vergelijken met de haakjes van een functie-aanroep in PHP. De eerste, 'binnenste' query is degene met de meeste haakjes. Die wordt als eerste uitgevoerd, waarna de resultaatset wordt doorgegeven als input aan de 'bovenliggende' query, waarna diens resultaatset wordt doorgegeven als input voor de 'bovenste' query zonder de haakjes.
Overigens wordt een query als in het voorbeeld vaker geschreven met JOINs:
Code (php)
1
2
3
4
2
3
4
SELECT klant.klantnaam FROM klant
INNER JOIN uitleen ON (uitleen.klant_id = klant.klant_id)
INNER JOIN boeken ON (boeken.boek_id = uitleen.boek_id)
WHERE boeken.jaar = 1993
INNER JOIN uitleen ON (uitleen.klant_id = klant.klant_id)
INNER JOIN boeken ON (boeken.boek_id = uitleen.boek_id)
WHERE boeken.jaar = 1993
Ik had eerder begrepen dat je voorzichtig moet zijn met subqueries in MySQL omdat de SQL optimizer vaak niet goed in staat is om onhandig geschreven queries te optimaliseren, waardoor ook allerlei indexes niet gebruikt zouden worden. Je zou dat per query kunnen bekijken met het EXPLAIN statement.
En wat is de relatie of link tussen de eerste querry met de querry's tussen de ()? Wordt deze vervangen door de laatste querrys of komen die samen in 1 resultaat?
In jouw geval krijg je dus alleen een lijst van klantnamen.
Vergelijk het met iets als
$x = kwadraat( 10 );
Dat levert je 100 op.
Ook krijg je 100 als je doet
$x = kwadraat( 2*5 )
als we ook de functie "verdubbel" kennen dan levert verdubbel( 5 ) je 10 op.
Dus
$x = kwadraat( verdubbel( 5 ) )
is wederom 100. Je ziet dus niet de 5 noch de 10 terug.
Net zo met je query.
De subquery's dienen, in jouw geval, voor het filteren van je resultaten. je haalt een lijst met boeken op, en wilt alleen de uitleen-acties met betrekking tot die boeken weken.
resultaat is due een lijst met uitleen-acties.
Je gebruikt dit tussen-resultaat wederom om je lijst met klanten te beperken.
Je wilt alleen de klanten hebben die voorkomen in de lijst met uitleen-acties.
Je kúnt wel iets doen met het ophalen van resultaten uit een subquery, maar dan gebruik je dat op een andere manier. Dan staat de subquery in het FROM (of join) deel van de query.
Maar evengoed:
ik denk dat een join-query meer is wat je nodig hebt.
Zeker als het om grotere aantallen gaat, zal je database waarschijnlijk je "IN (heeeele grote lijst)" niet lollig vinden.
Hoe is de opzet voor een join? Want ik vind een subselect niet echt leesbaar. En verwarrend.
Code (php)
1
2
3
4
5
2
3
4
5
SELECT klant.klantnaam
FROM boeken
JOIN uitleen ON uitleen.boek_id = boeken.boek_id
JOIN klant ON klant.klant_id = uitleen.klant_id
WHERE boeken.jaar = 1993
FROM boeken
JOIN uitleen ON uitleen.boek_id = boeken.boek_id
JOIN klant ON klant.klant_id = uitleen.klant_id
WHERE boeken.jaar = 1993
Je begin met selecteren van "boeken" uit jaar 1993. (regel 2 en 5)
Met regel 3 zoek je uit tabel uitleen alle uitleen van die boeken
Met regel 4 zoek je uit tabel klanten alle klanten van die uitleen
Op regel 1 toon je alleen de klantnaam
Gewijzigd op 26/04/2016 13:49:42 door Jan de Laet
Ok. bedankt voor de informatie. Dit is duidelijk. Ook bedankt aan de rest
Het enige verschil tussen Jans query en de mijne is dat de zijne meer rijen laat zien, ook als er geen informatie gevonden kan worden in de tabellen 'uitleen' en 'klant', omdat er via een LEFT JOIN gejoined wordt vanuit de tabel 'boeken'. In mijn query zitten INNER JOINs die alleen rijen tonen die in alle tabellen aanwezig zijn, zoals de query in je oorspronkelijke vraag.
Wel een verschil in onze aanpak is dat jij van klant naar uitleen naar boek werkt. Ik doe dat precies andersom. Ik had daar een reden voor, namelijk omdat de enige WHERE op boeken sloeg.
Ik weet niet zeker of dit in performance een beter resultaat geeft, maar ik verwacht van wel.
Overigens is JOIN (die ik gebruik) naar mijn beste weten in MySQL hetzelfde als een INNER JOIN, dus het aantal rijen zal hetzelfde zijn.