GROUP BY geeft niet het juiste resultaat
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
teams
+--+------+
|ID| TEAM |
|1 |Yellow|
|2 |Green |
|3 |Blue |
|4 |Red |
+--+------+
Players
+--+------+
|ID| NAME |
|1 |Ben |
|2 |Mike |
|3 |Jason |
+--+------+
Lineups
+---+---+
|PID|TID|
|1 |3 |
|2 |1 |
|2 |4 |
|3 |2 |
+--+----+
+--+------+
|ID| TEAM |
|1 |Yellow|
|2 |Green |
|3 |Blue |
|4 |Red |
+--+------+
Players
+--+------+
|ID| NAME |
|1 |Ben |
|2 |Mike |
|3 |Jason |
+--+------+
Lineups
+---+---+
|PID|TID|
|1 |3 |
|2 |1 |
|2 |4 |
|3 |2 |
+--+----+
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$sql = " SELECT teams.id teamsid, teams.team teamname, lineups.tid, players.name
FROM teams
LEFT JOIN lineups ON lineups.tid = teams.id
AND lineups.pid = 2
LEFT JOIN players ON lineups.pid = players.id
GROUP BY players.name
ORDER BY team
";
$result = mysqli_query($connection, $sql);
while($row = mysqli_fetch_assoc($result)){
echo $row['name'];
$checked = ($row['tid'] === NULL ? '' : ' checked="checked"');
?>
<label>
<input type="checkbox" <?php echo $checked; ?>><?php echo $row['teamname']; ?>
</label><?php
}
?>
$sql = " SELECT teams.id teamsid, teams.team teamname, lineups.tid, players.name
FROM teams
LEFT JOIN lineups ON lineups.tid = teams.id
AND lineups.pid = 2
LEFT JOIN players ON lineups.pid = players.id
GROUP BY players.name
ORDER BY team
";
$result = mysqli_query($connection, $sql);
while($row = mysqli_fetch_assoc($result)){
echo $row['name'];
$checked = ($row['tid'] === NULL ? '' : ' checked="checked"');
?>
<label>
<input type="checkbox" <?php echo $checked; ?>><?php echo $row['teamname']; ?>
</label><?php
}
?>
De voorlaatste regel in de query GROUP BY players.name zorgt ervoor dat de data niet word weergegeven zoals ik zou willen.
Zonder deze regel zou het resultaat zijn
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
"Ben"
<label><input type="checkbox" checked="checked">Groen</label>
"Ben"
<label><input type="checkbox" checked="checked">Rood</label>
<label><input type="checkbox">Geel</label>
"Ben"
<label><input type="checkbox" checked="checked">Groen</label>
"Ben"
<label><input type="checkbox" checked="checked">Rood</label>
Maar ik wil de player naam 1 keer laten voorkomen in het resultaat, ik dacht dan gebruik ik GROUP BY maar dit levert als resultaat op
Code (php)
1
2
3
2
3
<label><input type="checkbox">Geel</label>
"Ben"
<label><input type="checkbox" checked="checked">Rood</label>
"Ben"
<label><input type="checkbox" checked="checked">Rood</label>
Het resultaat dat ik graag zou willen is
Code (php)
1
2
3
4
5
2
3
4
5
"Ben"
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
Wat moet ik aanpassen hiervoor?
Gewijzigd op 08/02/2020 22:44:29 door Bryan De Baar
Is dit een pagina die aangeeft in welk team een (specifieke) speler opgesteld kan staan?
Je hebt sowieso een rare (?) conditie: AND lineups.pid = 2? Klopt dat?
En was dit hele gebeuren al niet behandeld / opgelost in een ander draadje? Is het echt gerechtvaardigd om hier een nieuw topic over te openen want gaat dit niet over precies hetzelfde?
Klopt in een ander topic hebben we de left join behandeld dit ging inderdaad om het uitlezen van de database en dan checked checkboxes in welk team een player zit.
Aangezien dit iets anders betreft heb ik een nieuw topic geopend wellis waar met het zelfde voorbeeld.
De tabel teams moet altijd volledig worden teruggeven zit de speler in bepaalde teams dan moeten deze checkboxes aangevinkt zijn.
Dit stukje hebben we dus behandeld maar nu wil ik nog de naam van de speler terug krijgen maar wel maar een keer, vandaar dat ik GROUP BY heb geprobeerd.
Maar dan krijg ik het verkeerde resultaat zoals bovenstaand uitgelegd.
Ik denk dat je voor die naam een aparte query moet maken.
Je query kan trouwens ook nog korter:
Code (php)
1
2
3
4
5
2
3
4
5
SELECT id, team, tid
FROM teams
LEFT JOIN lineups ON teams.id = lineups.tid
AND lineups.pid = 2
ORDER BY team
FROM teams
LEFT JOIN lineups ON teams.id = lineups.tid
AND lineups.pid = 2
ORDER BY team
Maak dan een query alleen op de players tabel met al ID = 2 als je dan een variable maakt en die laat invullen bij de player ID en de TID dan krijg je zowel de naam terug als je checkboxes.
dan krijg je dus zoiets
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$theid = 2;
$sql1 = "
SELECT id, team, tid
FROM teams
LEFT JOIN lineups ON teams.id = lineups.tid
AND lineups.pid = $theid
ORDER BY team
";
$result1 = mysqli_query($connection, $sql1);
$sql2 = "
SELECT name
FROM players
WHERE id = $theid
";
$result1 = mysqli_query($connection, $sql2);
//En hier je loopjes...
?>
$theid = 2;
$sql1 = "
SELECT id, team, tid
FROM teams
LEFT JOIN lineups ON teams.id = lineups.tid
AND lineups.pid = $theid
ORDER BY team
";
$result1 = mysqli_query($connection, $sql1);
$sql2 = "
SELECT name
FROM players
WHERE id = $theid
";
$result1 = mysqli_query($connection, $sql2);
//En hier je loopjes...
?>
Gewijzigd op 09/02/2020 17:12:23 door Jop B
Ik zou dus verwachten dat je enerzijds een soort van overzichtspagina van teams hebt, en als je op een team klikt, dat je een detailpagina te zien krijgt van het betreffende team met een lijstje van alle spelers, en de spelers die in de opstelling van het team staan zijn aangevinkt. Maar dit laatste kan dus met een enkele query.
Gewijzigd op 09/02/2020 22:51:10 door Thomas van den Heuvel
Thomas:
Als ik de details van Ben wil tonen dan wil ik de naam Ben 1 keer tonen.
Daarnaast moeten alle teams worden geladen (dit zijn checkboxes) en waar ben in voorkomt die moeten zijn aangevinkt.
De query voor de checkboxes hebben we in de andere topic behandeld maar ik krijg de naam Ben niet enkel terug.
Hij doet de naam of 2 keer teruggeven omdat hij in 2 teams voorkomt, en als ik dan de naam groepeer krijg ik van de teams alleen geel en rood terug.
Als je echt alles wilt tonen - alle teams met alle lineups (of per speler tot welk team zij behoren?) - dan lees je toch gewoon alles uit in een of meer queries en bouw je in PHP wat kleine datastructuren (in arrays)?
Maar als ik het goed begrijp is dit dus een soort van bewerkpagina. Wil je echt alle data tegelijkertijd kunnen wijzigen? Dit wordt al snel een onoverzichtelijke brei, zo niet visueel dan wel in code?
Ik zou voor een wat simpelere indeling gaan, waarbij je bijvoorbeeld ofwel alle data van een (enkele) speler wijzigt, een (enkel) team of wat dan ook. Het compartimenteren van informatie werkt doorgaans makkelijker.
Uiteraard kun je wel (totaal)overzichten uitdraaien met al deze informatie, maar die zijn dan "read only".
Ook is het handig om hier eerst "functioneel" over na te denken - wat wil je precies bereiken met zo'n pagina. Dan heb je namelijk ook een beter beeld van wat je gaat maken.
Het bovenstaande voorbeeld klopt ook niet? Je zegt dat je het groene en rode team aangevinkt wilt hebben, maar er is geen enkele speler (in jouw dataset) die in beide lineups staat? Speler 2 (Mike) is onderdeel van team geel (1) en rood (4).
Vandaar ook mijn verwarring - je hebt het over een pagina waarin alle teams getoond zouden moeten worden, maar in de query staat een verwijzing naar een specifieke speler (AND lineups.pid = 2). Dat rijmt niet helemaal? Of wil je één overzicht waarbij alle spelers per teams aangevinkt staan? Dus nogmaals: hoe zou de indeling van deze pagina moeten zijn, en lijkt het je echt een goed idee om zo alles bij elkaar te gooien?
Hi Thomas,
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
Naam: Mike
Opgesteld in groep(en):
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
Opgesteld in groep(en):
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
Gewijzigd op 10/02/2020 17:30:45 door Jop B
@Jop ja maar dat precieze vraagstuk is al in de eerdergenoemde thread behandeld, dus ik ga er daarom vanuit dat het hier een andere indeling betreft.
Quote:
De query voor de checkboxes hebben we in de andere topic behandeld maar ik krijg de naam Ben niet enkel terug.
Wat ik opmaak uit zijn vraag hier is dat als hij de naam van de speler (player) toevoegt aan zijn bestaande query dat deze dan 2x voorkomt in het resultaat als we uitgaan van id: 2 = Mike
Daarom heb ik bovenstaand voorbeeld gegeven om 2 aparte queries te maken: 1 voor de naam en 1 voor de teams met checkboxes.
In zijn eerste bericht geeft hij als voorbeeld dit aan als resultaat te willen ontvangen
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
1maal de naam //vraagstelling in dit topic
"Mike"
en de checkboxes van de teams //ander topic behandeld
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
"Mike"
en de checkboxes van de teams //ander topic behandeld
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
Dan kan ie toch het beste 2 queries maken of ben ik dan fout het denken?
- een array met speler info id => data
- een array met team info id => data
- een koppelarray met een "mapping" speler => team of vice versa
Hiermee ontkoppel je ook wat logica van de weergave en is het daar enkel een kwestie van het uitvoeren van loopjes over zo'n array, en dat je checkboxen aanvinkt door te controleren of een array index/waarde bestaat.
Hoe je dat verder precies uit je database trekt maakt dan ook geen biet meer uit, dus als het eenmaal in dat soort arrays zit kun je altijd nog over de optimalisatie van je queries nadenken zonder dat dat van invloed is op de weergave, en kun je dit in afzondering aanpassen, zolang dit maar dezelfde arrays oplevert. Zoals vanouds: verdeel en heers.
Gewijzigd op 10/02/2020 19:09:56 door Thomas van den Heuvel
Bryan De Baar op 08/02/2020 22:43:47:
De voorlaatste regel in de query GROUP BY players.name zorgt ervoor dat de data niet word weergegeven zoals ik zou willen.
Dat klopt, de SQL-standaard stelt dat alle kolommen die niet in een aggregate functie staan moeten worden vermeld in de GROUP BY, tenzij ze volledig afhankelijk zijn van een kolom die er wel in voorkomt. In MySQL heb je de FULL_GROUP_BY flag waarmee je dit aan of uit kan zetten.
Bryan De Baar op 08/02/2020 22:43:47:
Maar ik wil de player naam 1 keer laten voorkomen in het resultaat, ik dacht dan gebruik ik GROUP BY maar dit levert als resultaat op
Het resultaat dat ik graag zou willen is
Wat moet ik aanpassen hiervoor?
Code (php)
1
2
3
2
3
<label><input type="checkbox">Geel</label>
"Ben"
<label><input type="checkbox" checked="checked">Rood</label>
"Ben"
<label><input type="checkbox" checked="checked">Rood</label>
Het resultaat dat ik graag zou willen is
Code (php)
1
2
3
4
5
2
3
4
5
"Ben"
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
<label><input type="checkbox">Blauw</label>
<label><input type="checkbox">Geel</label>
<label><input type="checkbox" checked="checked">Groen</label>
<label><input type="checkbox" checked="checked">Rood</label>
Wat moet ik aanpassen hiervoor?
Dat de naam meerdere keren voorkomt in het resultaat is inherent aan MySQL, dit is zonder ingrepen niet te veranderen, het simpelste is om dit in php af te vangen:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$result = mysqli_query($connection, $sql);
$flag = 0;
while($row = mysqli_fetch_assoc($result)){
if (!$flag) {
echo $row['name'];
$flag = 1;
}
$checked = ($row['tid'] === NULL ? '' : ' checked="checked"');
?>
<label>
<input type="checkbox" <?php echo $checked; ?>><?php echo $row['teamname']; ?>
</label><?php
}
?>
$result = mysqli_query($connection, $sql);
$flag = 0;
while($row = mysqli_fetch_assoc($result)){
if (!$flag) {
echo $row['name'];
$flag = 1;
}
$checked = ($row['tid'] === NULL ? '' : ' checked="checked"');
?>
<label>
<input type="checkbox" <?php echo $checked; ?>><?php echo $row['teamname']; ?>
</label><?php
}
?>
Dan over de query zelf, in deze situatie lijkt het mij handiger een CROSS JOIN te gebruiken:
Code (php)
1
2
3
4
5
2
3
4
5
SELECT p.player_name, t.team_name, l.player_id
FROM players p
CROSS JOIN teams t
LEFT JOIN lineups l ON l.player_id = p.player_id AND l.team_id = t.team_id
WHERE p.player_id = 2
FROM players p
CROSS JOIN teams t
LEFT JOIN lineups l ON l.player_id = p.player_id AND l.team_id = t.team_id
WHERE p.player_id = 2
De CROSS JOIN geeft je alle mogelijke combinaties van teams / spelers, dit heeft als voordeel dat je dit kan gebruiken voor de benadering van zowel spelers en teams. Plus dat het ook werkt voor meerdere spelers en/of team (dit in tegenstelling met de oplossing via de LEFT JOIN)