bepaalde waarde tellen in de velden

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Dirk vandewiele

dirk vandewiele

07/10/2015 12:22:56
Quote Anchor link
Hoikes,

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
 
PHP hulp

PHP hulp

20/04/2024 13:32:46
 
Ben van Velzen

Ben van Velzen

07/10/2015 12:26:42
Quote Anchor link
Wacht, je hebt serieus w1 t/m w26? Waarom is dat niet genormaliseerd?
 
Thomas van den Heuvel

Thomas van den Heuvel

07/10/2015 12:35:02
Quote Anchor link
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.
 
Dirk vandewiele

dirk vandewiele

07/10/2015 12:45:32
Quote Anchor link
De velden w1 tem w26 zijn de speelweken. 0 staat voor verlies, 1 staat voor gelijkspel en 2 voor winst. X staat voor vrij deze week. De reden dat het zo is opgemaakt is omdat ik een beginner ben en dit klassementje opmaken in php, wat prima lukt, een hobby is. Nu wil ik per speler grafiekjes tekenen en zo maar daarvoor heb ik percentages nodig. Die grafiekjes teken ik met phpgraphlib, maar dit even ter zijde.

Ohja, sorry voor de schrijf fouten maar ik stuur via smartphone en heb geen brilletje ter beschikking waar ik ben :-)
 
Jan de Laet

Jan de Laet

07/10/2015 12:48:09
Quote Anchor link
Ben en Thomas hebben natuurlijk gelijk over het normaliseren, maar mocht dat nou een probleem zijn dan kan het zo (niet heel fraai dus)

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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


Met de CASE vervang je elke Wx = '2' door 1 en die tel je op.
 
Dirk vandewiele

dirk vandewiele

07/10/2015 12:54:25
Quote Anchor link
Natuurlijk hebben die mensen gelijk, netjes is het niet.
Ik zal eens aan de slag gaan met uw oplossing. Je hoort wel als het gelukt is.

Alvast bedankt.
 

07/10/2015 13:21:51
Quote Anchor link
Vervang in onderstaande query de tabelnaam met de daadwerkelijke naam van je tabel, en het getal 2 met het getal waarin je in alle kolommen wilt zoeken, en `id` = 3 is natuurlijk voor de account van de speler.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
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`


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)
PHP script in nieuw venster Selecteer het PHP script
1
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


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)
PHP script in nieuw venster Selecteer het PHP script
1
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;


Als je meerdere queries maakt helpt het om een VIEW te maken op de tabel speler_antwoord waarin de JOINs verwerkt zijn.
Gewijzigd op 07/10/2015 13:23:50 door
 
Ivo P

Ivo P

07/10/2015 16:56:39
Quote Anchor link
Je kunt natuurlijk bovenstaande beest van een query overnemen en dan blij constateren dat het werkt, maar je maakt je probleem alleen maar groter.

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.
 
Dirk vandewiele

dirk vandewiele

07/10/2015 18:48:31
Quote Anchor link
Er zijn maar 7 spelers. Er wordt exact 26 keer gespeeld. Alles draait lokaal, het is dus puur voor eigen gebruik. Natuurlijk hebben jullie gelijk, ik moest een tabel spelers gemaakt hebben en een tabel uitslagen, dit ging het alles makkelijker maken, maar het wordt dus niet uitgebreid, vandaar. Iedereen bedankt om te reageren en van zodra er tijd is ga ik aan de slag.

Groetjes
 

08/10/2015 09:11:31
Quote Anchor link
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.
Gewijzigd op 08/10/2015 09:12:44 door
 
Ivo P

Ivo P

08/10/2015 10:50:54
Quote Anchor link
Maar dat lijkt me in dit geval niet van toepassing.
 

08/10/2015 17:10:41
Quote Anchor link
Ik denk het ook niet. Ik denk dat de performancewinst zit in het feit dat het gedenormaliseerde model sneller te maken en makkelijker te begrijpen is, je kunt hem ook in 1x laten zien en editen in phpMyAdmin. Je kunt er alle kanten mee op.
Gewijzigd op 08/10/2015 17:11:04 door
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.