Cijfers uit mysql in de juiste html tabel krijgen
Code (php)
1
2
3
4
2
3
4
Ras jan feb mrt apr mei jun jul aug sep okt nov dec
Holsteiner 0 1 10 15 0 2 3 5 4 8 9 1
Aubrac 1 5 1 10 2 8 7 6 2 4 3 7
...
Holsteiner 0 1 10 15 0 2 3 5 4 8 9 1
Aubrac 1 5 1 10 2 8 7 6 2 4 3 7
...
En een mysql database als volgt opgebouwd:
Code (php)
1
2
3
4
2
3
4
id datum ras email aantal
1 2015-06-24 aubrac [email protected] 1
2 2015-06-23 Holsteiner [email protected] 1
...
1 2015-06-24 aubrac [email protected] 1
2 2015-06-23 Holsteiner [email protected] 1
...
Welke query kan ik nu gebruiken om de juiste waarden in de juiste kolommen te krijgen?
Ik heb voor de maand uit de datum te halen het volgende gebruikt MONTH(datum).
En de aantallen per ras zou ik kunnen optellen (een ras kan uiteraard meerdere keren voorkomen per maand) met SUM(ras).
Alleen zie ik niet het geheel en zeker ook niet hoe die dan in de juiste html kolom terecht komen (de juiste maand kolom).
Gewijzigd op 24/06/2015 14:34:02 door Brecht S
Code (php)
1
2
3
2
3
SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
Dit bak je in een subquery en daarna join je de tabel waarin je die gegevens hebt staan.
Ik ben in een goeie bui dus:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
m.month_no,
d.ras,
SUM(d.aantal)
FROM
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
LEFT JOIN
tabelnaam d
ON
m.month_no = MONTH(d.datum)
GROUP BY d.rasm, m.month_no
m.month_no,
d.ras,
SUM(d.aantal)
FROM
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
LEFT JOIN
tabelnaam d
ON
m.month_no = MONTH(d.datum)
GROUP BY d.rasm, m.month_no
Gewijzigd op 24/06/2015 22:40:04 door Ger van Steenderen
De waarden worden precies wel goed opgeteld en samengevoegd per ras. Alleen zie ik ook nog niet goed hoe je dit nu de cijfers (sum van de aantallen) in de juiste maandtabel kan 'duwen'.
Ik heb dit even in een while uitgelezen en krijg nu dit als resultaat:
Ik lees de waarden als test uit met:
Code (php)
Ik zie ook dat je ondertussen de GROUP BY hebt gewijzigd maar ditmaal met een fout in. d.rasm bestaat niet.
Gewijzigd op 24/06/2015 22:54:02 door Brecht S
Toevoeging op 24/06/2015 23:06:38:
Ik weet niet of je helemaal mee bent in het verhaal. Wat ik wil bereiken is het onderstaande gebaseerd op het resultaat uit je query:
Gewijzigd op 24/06/2015 23:08:00 door Brecht S
Dan zet je een cross join op de maand en het ras id.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT
m.month_no,
d.ras,
SUM(d.aantal)
FROM
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
CROSS JOIN
wedstrijd d
ON
m.month_no = MONTH(d.datum)
GROUP BY
d.ras, m.month_no
m.month_no,
d.ras,
SUM(d.aantal)
FROM
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
CROSS JOIN
wedstrijd d
ON
m.month_no = MONTH(d.datum)
GROUP BY
d.ras, m.month_no
Alle maanden die geen aantallen hebben (dus waarvan de SUM = 0) zijn nu verdwenen.
Nu moet ik die nog in de juiste maandkolom krijgen en dit lijkt niet zo eenvoudig.
Resultaat tot nu toe (uitgelezen met de <td>'s hierboven beschreven):
En in dit onderstaande formaat (maandtabellen) moet ik het krijgen:
Gewijzigd op 25/06/2015 15:58:49 door Brecht S
Die tabel kan je dan met een CROSS JOIN aan de maand no toevoegen en daarna met de LEFT JOIN op maand_no en ras de wedstrijd tabel.
Ik heb nu een tabel rassen met kolom id en kolom ras? Kan ik daarmee verder?
Toevoeging op 25/06/2015 21:08:40:
Is het zoiets wat je bedoeld?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
m.month_no,
d.ras,
SUM(d.aantal)
FROM
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
CROSS JOIN
rassen e
ON
e.ras = d.ras
LEFT JOIN
wedstrijd d
ON
m.month_no = MONTH(d.datum)
GROUP BY
d.ras, m.month_no
m.month_no,
d.ras,
SUM(d.aantal)
FROM
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
CROSS JOIN
rassen e
ON
e.ras = d.ras
LEFT JOIN
wedstrijd d
ON
m.month_no = MONTH(d.datum)
GROUP BY
d.ras, m.month_no
Gewijzigd op 25/06/2015 20:54:33 door Brecht S
Bijv:
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT * FROM
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
CROSS JOIN
(SELECT 'Brecht' ras UNION select 'Vuilnisbak') r
+ ------------- + ---------- +
| month_no | ras |
+ ------------- + ---------- +
| 1 | Brecht |
| 1 | Vuilnisbak |
| 2 | Brecht |
| 2 | Vuilnisbak |
| 3 | Brecht |
| 3 | Vuilnisbak |
| ... | ...... |
| 11 | Brecht |
| 11 | Vuilnisbak |
| 12 | Brecht |
| 12 | Vuilnisbak |
+ ------------- + ---------- +
(SELECT 1 as month_no UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
) m
CROSS JOIN
(SELECT 'Brecht' ras UNION select 'Vuilnisbak') r
+ ------------- + ---------- +
| month_no | ras |
+ ------------- + ---------- +
| 1 | Brecht |
| 1 | Vuilnisbak |
| 2 | Brecht |
| 2 | Vuilnisbak |
| 3 | Brecht |
| 3 | Vuilnisbak |
| ... | ...... |
| 11 | Brecht |
| 11 | Vuilnisbak |
| 12 | Brecht |
| 12 | Vuilnisbak |
+ ------------- + ---------- +
De rest kan je zelf bedenken.
Of moet ik die regel gewoon verder schrijven: (select 'aubrac' ras union select 'holsteiner' union select ...)?
En wat met die left join die er nu niet tussen staat?
Als ik wel toevoeg krijg ik eerst een lege tabel met de month_no in en dan pas een overzicht per maand.
En waarom moet ik dan een extra tabel rassen maken?
Ook de aantallen zijn belangrijk per maand_no
Gewijzigd op 26/06/2015 10:44:38 door Brecht S
Ook als je je rassen in een aparte tabel hebt zitten zou je de HTML-tabel nog dynamischer kunnen opbouwen.
Sla je resultaten op in een arraytje wat een beetje handig uit te lezen valt en controleer in de loop of er entries zijn voor die maand:
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
$rassen = array(1 => 'aubrac', 2=> 'simmental');
// je query, sla resultaten op in een array [ras][maand] => [aantal], bijvoorbeeld als volgt:
// ...
$rasAantallen = array(
1 => array(6 => 2), // ras id 1: aubrac, maand 6, aantal 2
2 => array(6 => 3), // ras id 2: simmental, maand 6, aantal 3
);
$maanden = array(1 => 'Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec');
// bouw je tabel
?><table>
<thead>
<tr>
<th>Ras</th><?php
foreach ($maanden as $label) {
?><th><?php echo $label ?></th><?php
}
?></tr>
</thead>
<tbody><?php
// doorloop alle rassen
foreach ($rassen as $rasId => $rasNaam) {
?><tr>
<td><?php echo $rasNaam ?></td><?php
// doorloop voor elk ras alle maanden
foreach ($maanden as $maandNr => $maandLabel) {
// als er voor dit ras en deze maand een aantal is, druk deze af, druk anders een spatie af
if (isset($rasAantallen[$rasId][$maandNr])) {
?><td><?php echo $rasAantallen[$rasId][$maandNr] ?></td><?php
} else {
?><td> </td><?php
}
}
?></tr><?php
}
?></tbody>
</table>
$rassen = array(1 => 'aubrac', 2=> 'simmental');
// je query, sla resultaten op in een array [ras][maand] => [aantal], bijvoorbeeld als volgt:
// ...
$rasAantallen = array(
1 => array(6 => 2), // ras id 1: aubrac, maand 6, aantal 2
2 => array(6 => 3), // ras id 2: simmental, maand 6, aantal 3
);
$maanden = array(1 => 'Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec');
// bouw je tabel
?><table>
<thead>
<tr>
<th>Ras</th><?php
foreach ($maanden as $label) {
?><th><?php echo $label ?></th><?php
}
?></tr>
</thead>
<tbody><?php
// doorloop alle rassen
foreach ($rassen as $rasId => $rasNaam) {
?><tr>
<td><?php echo $rasNaam ?></td><?php
// doorloop voor elk ras alle maanden
foreach ($maanden as $maandNr => $maandLabel) {
// als er voor dit ras en deze maand een aantal is, druk deze af, druk anders een spatie af
if (isset($rasAantallen[$rasId][$maandNr])) {
?><td><?php echo $rasAantallen[$rasId][$maandNr] ?></td><?php
} else {
?><td> </td><?php
}
}
?></tr><?php
}
?></tbody>
</table>
Gewijzigd op 26/06/2015 13:22:26 door Thomas van den Heuvel
Maanden plakken op elkaar en mei heeft geen 2 results en die 3 valt compleet buiten de maanden. Rasnaam staat nergens vermeld.
Gewijzigd op 26/06/2015 11:45:47 door Brecht S
Zelf ook eea uitproberen kan ook geen kwaad.
Verwacht niet dat er in 1x flawless code wordt gepost.
Gewijzigd op 26/06/2015 11:52:16 door Thomas van den Heuvel
Thomas van den Heuvel op 26/06/2015 11:32:15:
In plaats van de maandenruimte op te spannen in de database zelf kun je ook gewoon een for-loop gebruiken in PHP. Dan komt het maar niet uit 1 perfecte query die je in 1 loop kunt doorlopen, een beetje praktisch blijven mensen.
Sorry hoor, maar als je 10 verschillende rassen hebt dan zou je 120 queries hebben, en naar mijn mening is dat zeer onpraktisch.
@Brecht
Mijn vorige voorbeeld was bedoeld om je te laten zien wat voor resultaat een crossjoin oplevert. Als je de tweede subquery vervangt door de tabel met rassen, moet je zelf kunnen bedenken hoe je de LEFT JOIN op wedstrijden moet doen.
Ik ga het niet voor je voorkauwen, zelf nadenken kan ook geen kwaad.
Ger van Steenderen op 26/06/2015 12:25:56:
Sorry hoor, maar als je 10 verschillende rassen hebt dan zou je 120 queries hebben, en naar mijn mening is dat zeer onpraktisch.
Wait, what? Dat zie ik niet?
Hier verschillen wij van mening denk ik. Ik ben van mening dat vraagstukken aan je database in eerste instantie de juiste informatie ophalen, bij voorkeur in een beetje een handig formaat.
Vervolgens is het prima toegestaan om in PHP nog extra verwerkstappen uit te voeren om de data nog een beetje in de goede vorm te kneden, bijvoorbeeld door deze in een data-structuur te zetten (een array).
En tot slot ga je deze informatie uit je datastructuur gebruiken.
Dit levert enige overhead op, maar ook meer flexibiliteit.
Het nadeel van een "query (precies) op maat" is dat elke keer als je iets in het gebruik verandert, er een grote kans aanwezig is dat je de query moet aanpassen of zelfs moet herschrijven. Als je data meer in een algemene vorm ophaalt (waarbij niet al teveel aannames worden gedaan over het uiteindelijke gebruik) dan is het waarschijnlijk eenvoudiger om ergens onderweg (datastructuur, of zelfs pas bij het weergeven van de data) die aanpassing te doen.
De kans dat je een fout maakt bij een wijziging en het effect van die fout lijkt mij kleiner wanneer dat ergens onderweg (of aan het einde) gebeurt, in tegenstelling tot wanneer je dit in de query zelf doet, waar alles mee valt of staat.
Het enige wat mij nog rest is een oplossing te vinden om mijn resultaten van de query in een array te plaatsen zoals:
Code (php)
1
2
3
4
2
3
4
$rasAantallen2 = array(
1 => array(6 => 2), // ras id 1: aubrac, maand 6, aantal 2
2 => array(6 => 3), // ras id 2: simmental, maand 6, aantal 3
);
1 => array(6 => 2), // ras id 1: aubrac, maand 6, aantal 2
2 => array(6 => 3), // ras id 2: simmental, maand 6, aantal 3
);
Hiervoor moet ik terug op zoek. Wat een while in een array plaatsen lukt niet echt.
@Ger: met jouw code heb ik nog heel wat meer werk om die draaiende te krijgen. Ik denk wel dat ik weet wat je bedoeld. Alleen het nu nog in de praktijk gaan omzetten...
Ik wil beide mogelijkheden wel onder de knie hebben dus ik ga op zoek.
Gewijzigd op 26/06/2015 13:18:54 door Brecht S
Als je laat zien hoe je de query uitvoert dan kan ik laten zien hoe je het array opbouwt.
Ik denk dat ik hier best ook met CASE werk, niet? Is de maand = 1 dan is dat jan, enz... Of is dat niet nodig? En dan moet ik nog de array met de rassen koppelen aan die ID nummer...
Toevoeging op 26/06/2015 13:55:50:
Eerder iets in de zin van:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT
(SELECT CASE ras
WHEN 'aubrac' THEN 1
WHEN 'holsteiner' THEN 2
WHEN 'simmental' THEN 3
WHEN 'belgisch wit-blauw' THEN 4 END),
MONTH(datum) as m,
SUM(aantal) as s
FROM
wedstrijd";
(SELECT CASE ras
WHEN 'aubrac' THEN 1
WHEN 'holsteiner' THEN 2
WHEN 'simmental' THEN 3
WHEN 'belgisch wit-blauw' THEN 4 END),
MONTH(datum) as m,
SUM(aantal) as s
FROM
wedstrijd";
Gewijzigd op 26/06/2015 13:37:40 door Brecht S
Ik bedoelde meer in je PHP-code.
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
$rassen = array(1 => 'aubrac', 2 => 'holsteiner', 3 => 'simmental', 4 => 'belgisch wit-blauw', 5 => 'piemontese' , 6 => 'west-vlaams rood', 7 => 'black aberdeen', 8 => 'rubia gallega', 9 => 'wagyu kobe',
10 => 'chianina' );
// je query, sla resultaten op in een array [ras][maand] => [aantal], bijvoorbeeld als volgt:
// ...
//$rasAantallen = array(
//1 => array(6 => 2), // ras id 1: aubrac, maand 6, aantal 2
//2 => array(6 => 3), // ras id 2: simmental, maand 6, aantal 3
//3 => array(7 => 4), //
//);
$sql = "
SELECT
(SELECT CASE ras
WHEN 'aubrac' THEN 1
WHEN 'holsteiner' THEN 2
WHEN 'simmental' THEN 3
WHEN 'belgisch wit-blauw' THEN 4
ELSE 5 END) AS ras1,
MONTH(datum) as m,
SUM(aantal) as s
FROM
wedstrijd";
$res = mysql_query($sql) or die (mysql_error());
while($row = mysql_fetch_assoc($res))
{
$rasAantallen = array(
$row['ras1'] => array($row['m'] => $row['s']), // ras id 1: aubrac, maand 6, aantal 2
$row['ras1'] => array($row['m'] => $row['s']), // ras id 2: simmental, maand 6, aantal 3
$row['ras1'] => array($row['m'] => $row['s']), //
);
}
?>
<pre>
<?php print_r($rasAantallen); ?>
</pre>
<?php
$maanden = array(1 => 'Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec');
// bouw je tabel
?>
<table id="table-gastenlijst2" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Ras</th><?php
foreach ($maanden as $label) {
?><th><?php echo $label; ?></th><?php
}
?></tr>
</thead>
<tbody><?php
// doorloop alle rassen
foreach ($rassen as $rasId => $rasNaam) {
?><tr>
<td><?php echo $rasNaam; ?></td><?php
// doorloop voor elk ras alle maanden
foreach ($maanden as $maandNr => $maandLabel) {
// als er voor dit ras en deze maand een aantal is, druk deze af, druk anders een spatie af
if (isset($rasAantallen[$rasId][$maandNr])) {
?><td><?php echo $rasAantallen[$rasId][$maandNr]; ?></td><?php
} else {
?><td> </td><?php
}
}
?></tr><?php
}
?></tbody>
</table>
$rassen = array(1 => 'aubrac', 2 => 'holsteiner', 3 => 'simmental', 4 => 'belgisch wit-blauw', 5 => 'piemontese' , 6 => 'west-vlaams rood', 7 => 'black aberdeen', 8 => 'rubia gallega', 9 => 'wagyu kobe',
10 => 'chianina' );
// je query, sla resultaten op in een array [ras][maand] => [aantal], bijvoorbeeld als volgt:
// ...
//$rasAantallen = array(
//1 => array(6 => 2), // ras id 1: aubrac, maand 6, aantal 2
//2 => array(6 => 3), // ras id 2: simmental, maand 6, aantal 3
//3 => array(7 => 4), //
//);
$sql = "
SELECT
(SELECT CASE ras
WHEN 'aubrac' THEN 1
WHEN 'holsteiner' THEN 2
WHEN 'simmental' THEN 3
WHEN 'belgisch wit-blauw' THEN 4
ELSE 5 END) AS ras1,
MONTH(datum) as m,
SUM(aantal) as s
FROM
wedstrijd";
$res = mysql_query($sql) or die (mysql_error());
while($row = mysql_fetch_assoc($res))
{
$rasAantallen = array(
$row['ras1'] => array($row['m'] => $row['s']), // ras id 1: aubrac, maand 6, aantal 2
$row['ras1'] => array($row['m'] => $row['s']), // ras id 2: simmental, maand 6, aantal 3
$row['ras1'] => array($row['m'] => $row['s']), //
);
}
?>
<pre>
<?php print_r($rasAantallen); ?>
</pre>
<?php
$maanden = array(1 => 'Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec');
// bouw je tabel
?>
<table id="table-gastenlijst2" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Ras</th><?php
foreach ($maanden as $label) {
?><th><?php echo $label; ?></th><?php
}
?></tr>
</thead>
<tbody><?php
// doorloop alle rassen
foreach ($rassen as $rasId => $rasNaam) {
?><tr>
<td><?php echo $rasNaam; ?></td><?php
// doorloop voor elk ras alle maanden
foreach ($maanden as $maandNr => $maandLabel) {
// als er voor dit ras en deze maand een aantal is, druk deze af, druk anders een spatie af
if (isset($rasAantallen[$rasId][$maandNr])) {
?><td><?php echo $rasAantallen[$rasId][$maandNr]; ?></td><?php
} else {
?><td> </td><?php
}
}
?></tr><?php
}
?></tbody>
</table>
Maar de query werkt nog niet.
Gewijzigd op 26/06/2015 14:14:00 door Brecht S