Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[SQL] Huiswerk Frustratie > 9000

Pagina: 1
Acties:

  • Nynto
  • Registratie: December 2009
  • Laatst online: 09-08 23:01
Ik ben een behoorlijke beginner in SQL. Dit is onze huiswerk opdracht:

"Maak een SQL query die (in één resultset) alle benodigde gegevens levert om de pagina “archief uitslagen” te maken (of de sheet “uitslagen” in het Excel bestand met voorbeeldgegevens)."

We moeten van deze tabel (UITSLAG)

Afbeeldingslocatie: http://s21.postimg.org/wlzmn4fkn/tabel.jpg

deze Excel tabel nabootsen

Afbeeldingslocatie: http://s21.postimg.org/ew2zz78bb/excel.jpg

Dit is wat ik tot nu toe heb, maar ik krijg hier uiteraard vier keer de scores van Set 1...

SELECT WEDSTRIJDFORMULIER.*, INDELING.Klas,
CONCAT(SUM(UITSLAG.PuntenA), ' - ', SUM(UITSLAG.PuntenB)) AS Uitslag,
CONCAT(UITSLAG.ScoreA, ' - ', UITSLAG.ScoreB) AS 'Set 1',
CONCAT(UITSLAG.ScoreA, ' - ', UITSLAG.ScoreB) AS 'Set 2',
CONCAT(UITSLAG.ScoreA, ' - ', UITSLAG.ScoreB) AS 'Set 3',
CONCAT(UITSLAG.ScoreA, ' - ', UITSLAG.ScoreB) AS 'Set 4'
FROM WEDSTRIJDFORMULIER, INDELING, UITSLAG
WHERE INDELING.Team = WEDSTRIJDFORMULIER.TeamA
AND UITSLAG.WID = WEDSTRIJDFORMULIER.WID
GROUP BY UITSLAG.WID

Iemand een oplossing, zodat van iedere set apart de scores kan worden opgevraagd?

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 21-11 10:33
Wat jij nodig hebt zijn joins.

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Hoeft de query enkel in MySQL te werken? Je kunt de tabel bijvoorbeeld joinen met zichzelf op setnummer, maar let hierbij goed op je GROUP BY-clausule.

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


  • Nynto
  • Registratie: December 2009
  • Laatst online: 09-08 23:01
Ja, probleem is dat wij nog geen Joins behandeld hebben op school. Ik snap er vrij weinig van dus. |:(

  • Nynto
  • Registratie: December 2009
  • Laatst online: 09-08 23:01
CodeCaster schreef op maandag 13 januari 2014 @ 18:49:
Hoeft de query enkel in MySQL te werken? Je kunt de tabel bijvoorbeeld joinen met zichzelf op setnummer, maar let hierbij goed op je GROUP BY-clausule.
Hoe zou je dit doen dan? Ik heb nog niets van Joins meegekregen.

  • pickboy
  • Registratie: Februari 2006
  • Laatst online: 21-11 19:55
als er geen joins behandelt zijn is het blijkbaar de bedoeling om het zonder joins te doen.

  • Keiichi
  • Registratie: Juni 2005
  • Laatst online: 22-11 16:53
Ninto schreef op maandag 13 januari 2014 @ 18:55:
[...]


Ja, probleem is dat wij nog geen Joins behandeld hebben op school. Ik snap er vrij weinig van dus. |:(
Voordat je aan joins begint, even inlezen in verzamelingsleer: Wikipedia: Verzameling (wiskunde) . dan valt het kwartje wat beter op z'n plek.

Solar @ Dongen: http://solar.searchy.net/ - Penpal International: http://ppi.searchy.net/


  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

In dat geval lijkt me een subquery (met name een correlated subquery) handiger:

SQL:
1
2
CONCAT((SELECT u2.ScoreA FROM UITSLAG u2 WHERE u2.WID = UITSLAG.WID AND u2.Set = 1), ' - ',
       (SELECT u2.ScoreB FROM UITSLAG u2 WHERE u2.WID = UITSLAG.WID AND u2.Set = 1)) AS 'Set 1'


En hopelijk krijg je de volgende les dan uitleg over hoe je dit geheel kunt omtoveren tot JOIN, want ik vermoed dat je huidige query de wedstrijd met ID 12 laat vallen.

[ Voor 51% gewijzigd door CodeCaster op 13-01-2014 19:18 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


  • Nynto
  • Registratie: December 2009
  • Laatst online: 09-08 23:01
CodeCaster schreef op maandag 13 januari 2014 @ 19:12:
In dat geval lijkt me een subquery (met name een correlated subquery) handiger:

SQL:
1
2
CONCAT((SELECT u2.ScoreA FROM UITSLAG u2 WHERE u2.WID = UITSLAG.WID AND u2.Set = 1), ' - ',
       (SELECT u2.ScoreB FROM UITSLAG u2 WHERE u2.WID = UITSLAG.WID AND u2.Set = 1)) AS 'Set 1'


En hopelijk krijg je de volgende les dan uitleg over hoe je dit geheel kunt omtoveren tot JOIN, want ik vermoed dat je huidige query de wedstrijd met ID 12 laat vallen.
Dit werkt inderdaad, maar mag ik vragen hoe je aan die u2 komt?

  • Xepos
  • Registratie: September 2009
  • Laatst online: 16-11 01:34
Ninto schreef op maandag 13 januari 2014 @ 19:52:
[...]


Dit werkt inderdaad, maar mag ik vragen hoe je aan die u2 komt?
Dat is een ID je kon het ook gewoon blabla noemen.
Je zegt dat de tabel voortaan gaat benoemen als u2. Scheelt typwerk.

[ Voor 12% gewijzigd door Xepos op 13-01-2014 20:06 ]


  • Miyamoto
  • Registratie: Februari 2009
  • Laatst online: 20-11 21:15
Xepos schreef op maandag 13 januari 2014 @ 20:05:
[...]
Dat is een ID je kon het ook gewoon blabla noemen.
Je zegt dat de tabel voortaan gaat benoemen als u2. Scheelt typwerk.
>>
Dat is een alias je kon het ook gewoon blabla noemen.
Je zegt dat de tabel voortaan gaat benoemen als u2. Scheelt typwerk.

  • Nynto
  • Registratie: December 2009
  • Laatst online: 09-08 23:01
Ahhh, ok. Enorm bedankt voor alle info en hulp! Werd er even helemaal gek van 8)7

[ Voor 44% gewijzigd door Nynto op 13-01-2014 20:11 ]


  • las3r
  • Registratie: Augustus 2006
  • Laatst online: 22-11 13:04
Wat je feitelijk doet hier is een join, where x.iets = y.iets wordt een cross-join genoemd. Het is mij op deze manier ook aangeleerd op de Hogeschool.

Het probleem met cross-joins (en de reden dat iedereen begint met 'je zou dit met joins moeten doen') is dat deze zorgt voor performanceproblemen met grotere sets aan data. MySQL in dit geval gaat elke rij uit tabel x door, en elke rij uit tabel y om een match te maken. Bij 2 tabellen met elk 100 rows, worden in totaal dus 100x100 rijen in het geheugen geplaatst (10.000 records). Je kunt je voorstellen dat cross-joins met 5 tabellen met elk 1000 records als een flinke tijd langer duren.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ninto schreef op maandag 13 januari 2014 @ 18:55:
[...]


Ja, probleem is dat wij nog geen Joins behandeld hebben op school. Ik snap er vrij weinig van dus. |:(
Feitelijk doe je in je eerste voorbeeld zelf al een JOIN alleen dan op een "oude" manier. Je zie in jouw FROM clause namelijk al meerdere tabellen staan. Later in de WHERE clause specificeer je dan de join conditie.

Ik zou meteen aanleren om dat op een andere manier te doen.

Jij doet het bijvoobeeld op deze manier
SQL:
1
2
3
SELECT *
FROM TabelA, TabelB
WHERE TabelA.PrimaryKey = TabelB.ForeignKey

Dat is echter hetzelfde als
SQL:
1
2
3
4
SELECT *
FROM TabelA
INNER JOIN TabelB
    ON TabelA.PrimaryKey = TabelB.ForeignKey

Deze syntax heeft als voordeel dat je in een oogopslag ziet wat de join conditie is, en anders moet je die zelf maar gaan zoeken in de WHERE clause. Bij een enkele join is dat nog niet zo'n probleem, maar bij meerdere join's wordt jouw manier steeds on overzichtelijker. Ook zou ik het gebruik van aliassen aanraden, zeker aangezien je meerdere malen dezelfde tabel wil joinen ( Je wil immer 4 uitslagen, die uit dezelfde tabel komen ).

Dan krijg je iets als
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT w.*, i.*, set1.*, set2.*, set3.*, set4.*
FROM Wedstrijdformulier w
INNER JOIN Indeling i
    ON w.TeamA = i.Team
INNER JOIN Uitslag set1
    ON w.WID = set1.WID
    AND set1.WID = 1
INNER JOIN Uitslag set2
    ON w.WID = set1.WID
    AND set1.WID = 2
INNER JOIN Uitslag set3
    ON w.WID = set1.WID
    AND set1.WID = 3
INNER JOIN Uitslag set4
    ON w.WID = set1.WID
    AND set1.WID = 4
[WHERE .....]
[GROUP BY ......]
[HAVING ....]

De selectie met * kun je dan ook beter uitschrijven naar de velden die je wil hebben
las3r schreef op dinsdag 14 januari 2014 @ 07:10:
Het probleem met cross-joins (en de reden dat iedereen begint met 'je zou dit met joins moeten doen') is dat deze zorgt voor performanceproblemen met grotere sets aan data. MySQL in dit geval gaat elke rij uit tabel x door, en elke rij uit tabel y om een match te maken. Bij 2 tabellen met elk 100 rows, worden in totaal dus 100x100 rijen in het geheugen geplaatst (10.000 records). Je kunt je voorstellen dat cross-joins met 5 tabellen met elk 1000 records als een flinke tijd langer duren.
Bij een beetje RDBMS zal deze manier performance wise niks onder doen voor de nettere manier, want de query optimizer zal zien dat de query gewoon exact hetzelfde is, en ik verwacht dan ook een gelijk query plan. Echter is de leesbaarheid van je query ook belangrijk, je geeft gewoon veel duidelijker aan wat je wil, en dat is erg belangrijk.

[ Voor 21% gewijzigd door Woy op 14-01-2014 09:18 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Woy schreef op dinsdag 14 januari 2014 @ 09:14:
[...]
Deze syntax heeft als voordeel dat je in een oogopslag ziet wat de join conditie is, en anders moet je die zelf maar gaan zoeken in de WHERE clause. Bij een enkele join is dat nog niet zo'n probleem, maar bij meerdere join's wordt jouw manier steeds on overzichtelijker.
Deze syntax heeft niet enkel met leesbaarheid te maken, maar ook met het correct schrijven van de join.

je kan perfect schrijven:

SQL:
1
2
SELECT *
FROM A, B;

Zo maak je echter wel een cartesiaans product tussen je 2 tabellen.

Bij deze syntax:
SQL:
1
2
3
4
SELECT *
FROM A
INNER JOIN B
ON A.ID = B.ID;


kan je de join-conditie niet weglaten, want dan zal je databank een syntaxerror geven.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op dinsdag 14 januari 2014 @ 13:21:
[...]


Deze syntax heeft niet enkel met leesbaarheid te maken, maar ook met het correct schrijven van de join.

je kan perfect schrijven:

SQL:
1
2
SELECT *
FROM A, B;

Zo maak je echter wel een cartesiaans product tussen je 2 tabellen.

Bij deze syntax:
SQL:
1
2
3
4
SELECT *
FROM A
INNER JOIN B
ON A.ID = B.ID;


kan je de join-conditie niet weglaten, want dan zal je databank een syntaxerror geven.
Puur een duidelijkere syntax dus ;) Je kan met INNER JOIN ook gewoon een cartesiaans product krijgen hoor, gewoon als join conditie 1 = 1 opnemen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1