Queries na normaliseren
Ik heb de tutorial gevolgd om een database te normaliseren en dat is wel gelukt denk ik. Ik zit nu alleen met het probleem dat het ophalen van de gegevens echt een stuk lastiger is geworden en na een hele poos zitten te klooien met queries heb ik besloten om hier toch maar de vraag te stellen :
Ik heb gewoon een oefenscenario gemaakt alsvolgt; Een systeem houd bij welke hobbies een persoon heeft. Deze hobbies zijn tevens van een bepaald thema. De database ziet er alsvolgt uit:
tbl_persoon
persoon_id
naam
adres
woonplaats
tbl_persoon_hobbies
persoon_id
hobby_id
tbl_hobbies
hobby_id
hobby_naam
hobby_tijd
tbl_hobbies_type
hobby_id
hobbytype_id
tbl_type
hobbytype_id
hobbytype_naam
Ik wil dan (mbv een invoerscherm die ik later maak) de volgende zoekopdracht uitvoeren:
Ik wil de NAW gegevens van alle personen die een hobby hebben met het type 'outdoor' (dus hobbytype_naam = outdoor).
Ik heb tot nu toe de volgende query al maar ik weet nu niet hoe ik verder moet:
SELECT persoon.naam, persoon.adres, persoon.woonplaats
FROM tbl_persoon AS persoon
INNER JOIN (tbl_hobbies as hobby
INNER JOIN
tbl_persoon_hobbies as ph
on ph.hobby_id = hobby.hobby_id)
ON ph.persoon_id = persoon.persoon_id WHERE persoon.naam = "sjaak"
(WHERE persoon.naam = "sjaak" moet later worden veranderd naar WHERE hobbytype_naam = "eenhobbynaam").
Kan iemand mij hiermee helpen?
Toevoeging op 05/12/2012 14:41:39:
Nog verder gaan zoeken en ik denk dat ik em nu toch heb :)
SELECT persoon.naam, persoon.adres, persoon.woonplaats
FROM tbl_persoon as persoon INNER JOIN tbl_persoon_hobbies ph
ON persoon.persoon_id = ph.persoon_id JOIN tbl_hobbies as h
ON ph.hobby_id = h.hobby_id JOIN tbl_hobbies_type as ht
ON h.hobby_id = ht.hobby_id JOIN tbl_type as type
ON ht.hobby_id = type.hobbytype_id
WHERE type.hobbytype = 'outdoor'
Als je bijvoorbeeld de hobbies weer aan de personen wilt hangen knoop je eerst de tabel persoon_bobbies aan de persoon tabel:
Code (php)
1
2
3
2
3
SELECT a.persoon_id, naam, adres, woonplaats
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id;
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id;
Vervolgens knoop je aan de (virtuele) tabel die ontstaat de hobbies tabel
Code (php)
1
2
3
4
2
3
4
SELECT a.persoon_id, naam, adres, woonplaats, hobby_naam, hobby_tijd
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
Merk op dat je niet allerlei haakjes nodig hebt om die joins te scheiden.
Wil je nu alle personen hebben die hobby X hebben dan kan je gewoon het volgende doen:
Code (php)
1
2
3
4
5
2
3
4
5
SELECT a.persoon_id, naam
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id
WHERE hobby_naam = 'X';
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id
WHERE hobby_naam = 'X';
En dan een persoonlijke tip. Om alle queries die je daarna maakt om data te selecteren wat simpeler te maken zou ik views definieren. Voor bovenstaande kan je bijvoorbeeld de volgende view maken:
Code (php)
1
2
3
4
5
2
3
4
5
CREATE VIEW v_persoon_hobbies AS
SELECT a.persoon_id, naam, adres, woonplaats, hobby_naam, hobby_tijd
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
SELECT a.persoon_id, naam, adres, woonplaats, hobby_naam, hobby_tijd
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
Vervolgens kan je select statement dan zijn:
Een view is niets meer dan een virtuele tabel. Je maakt een view een keer aan op de database en vervolgens kan je elke keer weer gebruiken. Het eerder SELECT statement met de joins werkt dus in feite precies hetzelfde als met bovenstaande view. Het voordeel van een view is dat je niet elke keer weer de joins hoeft te maken. Qua snelheid maakt het niets uit.
Erwin H op 05/12/2012 14:52:08:
op zich ben je goed bezig. Via joins link je de tabellen aan elkaar en zorg je ervoor dat je dus de gegevens aan elkaar knoopt. Doe het gewoon tabel voor tabel en je komt er vanzelf.
Als je bijvoorbeeld de hobbies weer aan de personen wilt hangen knoop je eerst de tabel persoon_bobbies aan de persoon tabel:
Vervolgens knoop je aan de (virtuele) tabel die ontstaat de hobbies tabel
Merk op dat je niet allerlei haakjes nodig hebt om die joins te scheiden.
Wil je nu alle personen hebben die hobby X hebben dan kan je gewoon het volgende doen:
En dan een persoonlijke tip. Om alle queries die je daarna maakt om data te selecteren wat simpeler te maken zou ik views definieren. Voor bovenstaande kan je bijvoorbeeld de volgende view maken:
Vervolgens kan je select statement dan zijn:
Een view is niets meer dan een virtuele tabel. Je maakt een view een keer aan op de database en vervolgens kan je elke keer weer gebruiken. Het eerder SELECT statement met de joins werkt dus in feite precies hetzelfde als met bovenstaande view. Het voordeel van een view is dat je niet elke keer weer de joins hoeft te maken. Qua snelheid maakt het niets uit.
Als je bijvoorbeeld de hobbies weer aan de personen wilt hangen knoop je eerst de tabel persoon_bobbies aan de persoon tabel:
Code (php)
1
2
3
2
3
SELECT a.persoon_id, naam, adres, woonplaats
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id;
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id;
Vervolgens knoop je aan de (virtuele) tabel die ontstaat de hobbies tabel
Code (php)
1
2
3
4
2
3
4
SELECT a.persoon_id, naam, adres, woonplaats, hobby_naam, hobby_tijd
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
Merk op dat je niet allerlei haakjes nodig hebt om die joins te scheiden.
Wil je nu alle personen hebben die hobby X hebben dan kan je gewoon het volgende doen:
Code (php)
1
2
3
4
5
2
3
4
5
SELECT a.persoon_id, naam
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id
WHERE hobby_naam = 'X';
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id
WHERE hobby_naam = 'X';
En dan een persoonlijke tip. Om alle queries die je daarna maakt om data te selecteren wat simpeler te maken zou ik views definieren. Voor bovenstaande kan je bijvoorbeeld de volgende view maken:
Code (php)
1
2
3
4
5
2
3
4
5
CREATE VIEW v_persoon_hobbies AS
SELECT a.persoon_id, naam, adres, woonplaats, hobby_naam, hobby_tijd
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
SELECT a.persoon_id, naam, adres, woonplaats, hobby_naam, hobby_tijd
FROM tbl_persoon a
LEFT JOIN tbl_persoon_hobbies b ON a.persoon_id = b.persoon_id
LEFT JOIN tbl_hobbies c ON b.hobby_id = c.hobby_id;
Vervolgens kan je select statement dan zijn:
Een view is niets meer dan een virtuele tabel. Je maakt een view een keer aan op de database en vervolgens kan je elke keer weer gebruiken. Het eerder SELECT statement met de joins werkt dus in feite precies hetzelfde als met bovenstaande view. Het voordeel van een view is dat je niet elke keer weer de joins hoeft te maken. Qua snelheid maakt het niets uit.
Ah hartstikke bedankt, van views had ik nog niet gehoord. Maar als ik een view aanmaak en een dag later update ik een tabel, wordt dan ook mijn view 'geupdate' zeg maar?
Als je de structuur van een tabel aanpast moet je de VIEW een dropje geven, en opnieuw aanmaken.
Indien je de gegevens in de tabel update worden deze gewoon doorgevoerd in de VIEW
Ik las het 'een dag later update ik een tabel' als een structuur update van de tabel, niet als een update van de data in de tabel. Maar je hebt gelijk Ger dat het niet helemaal duidelijk is uit de vraag. Dus jouw verduidelijk is inderdaad wel belangrijk.
Misschien was mijn vraagstelling niet helemaal duidelijk (het SQL jargon is nieuw dus misschien dat daardoor verwarring ontstaat).
Als ik in ieder geval nieuwe data in mijn originele tabel toevoeg wordt deze data ook automatisch meegenomen in de view als ik et goed begrijp.
Ja dat begrijp je goed. Een beetje simpel gesteld is een view een opgeslagen subquery.