bepaalde waarde tellen in de velden
Mijn database is opgemaakt met de volgende velden,
Id, speler en dan w1 tot en met w26.
Nu wil ik graag tellen hoever keer bvb de waarde 2 voorkomt in de velden w1 tot en met w26 maar niet bvb het veld id want daar komt ook een 2 in voor. Mogelijke waarden in die velden zijn, leeg. 0, 1 ,2 of X.
Ik probeerde met mysql num rows maar het is logisch dat dit niet werkt. Met mysql num fields bind ik het niet.
Ik wil dus weten hoever keer een 2 voorkomt bij bvb speler Marc die id 3 heeft.
Tia
Wacht, je hebt serieus w1 t/m w26? Waarom is dat niet genormaliseerd?
Misschien kan de topicstarter eerst uitleggen wat die w1 t/m w26 precies betekenen, en waarom (inderdaad) deze waarden niet in een aparte tabel opgeslagen zijn. Dat laatste zou dit vraagstuk namelijk een stuk eenvoudiger (zo niet triviaal) maken.
Ohja, sorry voor de schrijf fouten maar ik stuur via smartphone en heb geen brilletje ter beschikking waar ik ben :-)
Code (php)
1
2
3
4
5
6
2
3
4
5
6
SELECT id, speler,
CASE WHEN w1 = '2' THEN 1 ELSE 0 END +
CASE WHEN w2 = '2' THEN 1 ELSE 0 END +
.. herhaal voor alle w's tot/met
CASE WHEN w26 = '2' THEN 1 ELSE 0 END AS aantalkeer2
FROM jouwtabel
CASE WHEN w1 = '2' THEN 1 ELSE 0 END +
CASE WHEN w2 = '2' THEN 1 ELSE 0 END +
.. herhaal voor alle w's tot/met
CASE WHEN w26 = '2' THEN 1 ELSE 0 END AS aantalkeer2
FROM jouwtabel
Met de CASE vervang je elke Wx = '2' door 1 en die tel je op.
Ik zal eens aan de slag gaan met uw oplossing. Je hoort wel als het gelukt is.
Alvast bedankt.
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
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
SELECT
SUM(n) AS `totaal`
FROM
( SELECT COUNT(*) AS `n` FROM `tabelnaam` WHERE `id` = 3 AND `w1` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w2` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w3` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w4` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w5` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w6` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w7` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w8` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w9` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w10` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w11` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w12` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w13` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w14` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w15` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w16` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w17` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w18` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w19` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w20` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w21` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w22` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w23` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w24` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w25` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w26` = 2
) AS `temp`
SUM(n) AS `totaal`
FROM
( SELECT COUNT(*) AS `n` FROM `tabelnaam` WHERE `id` = 3 AND `w1` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w2` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w3` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w4` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w5` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w6` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w7` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w8` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w9` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w10` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w11` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w12` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w13` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w14` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w15` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w16` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w17` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w18` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w19` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w20` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w21` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w22` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w23` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w24` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w25` = 2
UNION SELECT COUNT(*) FROM `tabelnaam` WHERE `id` = 3 AND `w26` = 2
) AS `temp`
Toevoeging op 07/10/2015 13:35:20:
De anderen bedoelen met normaliseren is dat je hetzelfde soort gegeven niet over meerdere kolommen verdeelt, maar over meerdere tabellen. Dan kun je een verdeling krijgen als:
TABEL speler:
+ KOLOM id
+ KOLOM naam
TABEL antwoord:
+ KOLOM id
+ KOLOM volgnummer
+ KOLOM waarde
+ KOLOM tekst
TABEL speler_antwoord:
+ KOLOM speler_id
+ KOLOM antwoord_id
Nadeel is wel dat je dan eerst een query moet schrijven om alles te kunnen zien, in plaats van op de tabelnaam te klikken. Dat wordt dan iets als
Code (php)
1
2
3
4
5
2
3
4
5
SELECT speler.naam, speler_antwoord.tekst
FROM speler_antwoord
LEFT JOIN speler ON (speler.id = speler_antwoord.speler_id)
LEFT JOIN antwoord ON (antwoord.id = speler_antwoord.antwoord_id)
ORDER BY speler.naam, antwoord.volgnummer
FROM speler_antwoord
LEFT JOIN speler ON (speler.id = speler_antwoord.speler_id)
LEFT JOIN antwoord ON (antwoord.id = speler_antwoord.antwoord_id)
ORDER BY speler.naam, antwoord.volgnummer
Een ander nadeel in deze constructie is dat het ietsje ingewikkelder wordt om ervoor te zorgen dat een enkele speler niet meerdere dezelfde antwoorden geeft. En als je mogelijk wilt maken dat een speler vaker een rijtje antwoorden mag geven, dan moet je met nog een tabel werken als:
TABEL toets
+ KOLOM id
+ KOLOM datum
en dan de tabel speler_antwoord uitbreiden met een kolom toets_id. En ja, je kunt dan ook de kolom speler_id verplaatsen naar de tabel toets, het is maar net wat handig is.
Toevoeging op 07/10/2015 13:38:27:
Als je dat allemaal hebt gedaan wordt een query op je data eenvoudiger, je kunt dan volstaan met:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
SELECT
SUM(antwoord.waarde) AS `Totaal`
FROM
speler_antwoord
LEFT JOIN antwoord ON (antwoord.id = speler_antwoord.antwoord_id)
WHERE
speler_id = 3;
SUM(antwoord.waarde) AS `Totaal`
FROM
speler_antwoord
LEFT JOIN antwoord ON (antwoord.id = speler_antwoord.antwoord_id)
WHERE
speler_id = 3;
Als je meerdere queries maakt helpt het om een VIEW te maken op de tabel speler_antwoord waarin de JOINs verwerkt zijn.
Stap zo snel mogelijk over op een genormaliseerd model, want hoe langer je wacht, hoe meer code er gebaseerd gaat zijn op het foute model.
Ik vraag me om te beginnen af, waarom er 26 speelweken zijn. Een jaar bevat 52, of 53!, weken.
Dus kans is aanwezig dat er meer dan 26 gaan komen? Dan zul je naast je tabel ook alle query's moeten aanpassen.
En wat als we een tweede jaar ingaan? Wordt dan de data van het vorige jaar gewist?
Zou je een tabel hebben met de kolommen "speelronde" en "seizoen", dan kan in seizoen eenvoudig een 2e, 3e en 10e jaar opslagen worden, en raak je geen oude data kwijt.
Ja, het is even wat moeite, maar je komt alleen maar verder in de knoop als je het uitstelt.
Groetjes
Quote:
<...> hoe langer je wacht, hoe meer code er gebaseerd gaat zijn op het foute model.
In het algemeen is normalisatie nuttig, anders hadden we daarvoor geen databases. Maar denormalisatie is niet per sé fout. Je kunt er bewust voor kiezen om performancewinst te halen, als het toepassen van een of meerdere JOINs zwaar weegt op de beschikbare resources.
Je kunt JOINs sneller maken door gebruik van indices. Omdat indices ook moeten worden geadministreerd door de database zijn ze pas effectief wanneer de grootte van de opgevraagde subset kleiner is dan ruwweg 15% van de totale dataset.
Maar dat lijkt me in dit geval niet van toepassing.