Query: Hoe aanpakken?
Nu wil ik dat je met checkboxes kleuren kan selecteren. Dus als je kiest [wit] [zwart] en [rood], dat alle beesten met die kleuren (ongeacht de volgorde in de kolom) tevoorschijn komen.
Weet iemand welke functie je daarvoor kan gebruiken?
Of wil je kunnen kiezen of het kleur X en kleur Y en kleur Z is (alles inclusief), of kleur X en/of kleur Y en/of kleur Z (alles optioneel)?
NB
Ze mogen wel meer kleuren hebben. Dus als er een dier is dat bijv. wit/rood/zwart/beige is dan moet die er ook uitrollen.
Gewijzigd op 21/02/2016 00:36:35 door marina janssen
Dan mag je een tabel kleuren aanmaken:
En vervolgens mag je een koppeltabel maken (user_kleur):
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
user_id Kleur_id
================
1 1 // gebruiker 1 heeft kleur Wit geselecteerd
1 3 // gebruiker 1 heeft kleur Zwart geselecteerd
2 1 // gebruiker 2 heeft kleur Wit geselecteerd
2 2 // gebruiker 2 heeft kleur Rood geselecteerd
2 3 // gebruiker 2 heeft kleur Zwart geselecteerd
...
================
1 1 // gebruiker 1 heeft kleur Wit geselecteerd
1 3 // gebruiker 1 heeft kleur Zwart geselecteerd
2 1 // gebruiker 2 heeft kleur Wit geselecteerd
2 2 // gebruiker 2 heeft kleur Rood geselecteerd
2 3 // gebruiker 2 heeft kleur Zwart geselecteerd
...
Elk record in die laatste tabel is een aangevinkte checkbox in je formulier (van een bepaalde gebruiker).
Nu wil je weten welke kleuren gebruiker 1 geselecteerd heeft:
Code (php)
1
2
3
2
3
SELECT k.id, k.kleur FROM kleur k
JOIN user_kleur uk ON k.id = uk.kleur_id
WHERE k.user_id = ?
JOIN user_kleur uk ON k.id = uk.kleur_id
WHERE k.user_id = ?
- In bovenstaande sql wordt gebruik gemaakt van JOIN om twee tabellen te koppelen
- Ook worden aliasses gebruikt. k staat voor de tabel 'kleur' en uk staat voor de tabel 'user_kleur'
- Op de plek van het vraagteken moet het ID van de gebruiker komen
Gewijzigd op 21/02/2016 11:55:27 door Frank Nietbelangrijk
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT d.naam,
GROUP_CONCAT(k.kleur ORDER BY k.kleur SEPARATOR '/') kleuren
FROM dieren d
JOIN dieren_kleuren c
ON d.dier_id = c.dier_id
JOIN kleuren k
ON c.kleur_id = k.kleur_id
WHERE c.kleur_id IN (1,3)
GROUP BY d.naam
HAVING COUNT(*) >= 2
GROUP_CONCAT(k.kleur ORDER BY k.kleur SEPARATOR '/') kleuren
FROM dieren d
JOIN dieren_kleuren c
ON d.dier_id = c.dier_id
JOIN kleuren k
ON c.kleur_id = k.kleur_id
WHERE c.kleur_id IN (1,3)
GROUP BY d.naam
HAVING COUNT(*) >= 2
Gewijzigd op 22/02/2016 09:21:54 door Ger van Steenderen
Gewijzigd op 21/02/2016 11:53:36 door Frank Nietbelangrijk
Geef de kleur een code dat een getal is wat een macht van 2 is:
wit = 1 (2 tot de macht 0)
zwart = 2 (2 tot de macht 1)
rood = 4 (2 tot de macht 2)
(enzovoorts, 8, 16, 32, 64 etc.)
In je "beesten" tabel kun je dan in één kolom de kleuren die een beest rijk is opslaan. Dit is dan de optelsom van deze codes. Bijvoorbeeld een witrood (of roodwit) beest heeft kleurcode 5 (1 + 4), een witzwart (of zwartwit) beest heeft code 3 (1 + 2).
Omdat de kleurcode is opgebouwd uit getallen die een macht van 2 zijn, is elke kleur uniek afleidbaar uit deze optelsom.
En hoe lees je dit weer uit een tabel als je op zoek bent naar een of meer specifieke kleuren? Dit doe je (onder andere) met de bitwise operator &. Deze operator werkt op twee waarden (operanden) net zoals de operator + werkt op A en B in de rekensom A + B. Maar wat is de uitkomst van A & B? Deze operator vergelijkt elke overeenkomende bit (lees: macht van 2) in A en B met elkaar. De uitkomst van deze som is de optelsom van alle bitjes die zowel in A als B op "1" stonden.
Je moet het zo zien, elk getal is te representeren als een rij nullen en enen die overeenkomen met machten van 2. Hierbij lees je zo'n bitreeks van recht naar links. Neem bijvoorbeeld 10110 binair, dit komt overeen met (gelezen van rechts naar links):
0 x 2 tot de macht 0 = 0 +
1 x 2 tot de macht 1 = 2 +
1 x 2 tot de macht 2 = 4 +
0 x 2 tot de macht 3 = 0 +
1 x 2 tot de macht 4 = 16
-------------------------
22 decimaal.
Stel dat je wilt weten of de tweede bit en de derde bit (vanaf rechts gezien) "aan" staan, dan kun je dit vergelijken met het getal 0 + 2 + 4 = 6 via de & operator. De uitkomst van deze som moet ook 6 zijn.
Dit zou je bijvoorbeeld in MySQL als volgt kunnen doen:
De uitkomst hiervan is ook 6, dus de tweede en de derde bit van 22 staan aan.
Op een andere manier weergegeven:
En op eenzelfde wijze, mogelijk heb je de parallel met je kleurcodes al gezien, kun je een beest-kleurcode vergelijken met een gewenste kleur(combinatie).
Wat betreft het laatste voorbeeld met kleurcodes: stel ik heb wit, zwart en rood aangevinkt, dan komt de kat die zwart/wit/rood/beige is er dus niet uit rollen, vrees ik.
Stel:
zwart = 1
wit = 2
rood = 4
beige = 8
Wat je wilt is zwart + wit + rood = 7.
De kat met zwart + wit + rood + beige = 15.
15 & 7 is nog steeds 7. Oftewel, de selectie zwart + wit + rood levert ook beesten met zwart + wit + rood + whatever op.
Ik zit hier al de hele middag naar te kijken maar tis alsof je chinees praat, dat van die kleurcodes begrijp ik nog wel maar hoe uit te lezen snap ik echt h e l e m a a l n i k s van
kan het niet makkelijker?
Ik zou gaan voor Franks benadering met een koppeltabel gaan
Ook, als je wat boolse logica kent en kunt (& staat niet ver af van && en die zou, als je met PHP of JavaScript werkt, toch al redelijk vertrouwd moeten zijn) en enigszins kunt tellen in n-tallige stelsels (je bent het 10-tallige stelsel al gewend, de inwoners zijn de cijfers 0 t/m 9) dan staat het binaire stelsel (inwoners 0 en 1) hier ook niet zo ver vanaf. Maar ja, als je geen lijn kunt bespeuren in dit alles dan begrijp ik dat het lastig is. Wanneer je je dit eigen hebt gemaakt en terugkijkt is het eigenlijk meer van hetzelfde maar in een andere verschijningsvorm. In de vorm zit niet de moeilijkheid, want die kende je in zekere zin al.
Je zou "&" ook kunnen zien als een functie die twee argumenten accepteert. Als je begrijpt wat je invoert, en hoe de uitvoer totstand komt, dan snap je ook wat "&" in feite doet. Je zou dit simpelweg kunnen zien als de functionaliteit van &&, die twee booleans (twee bitjes, 0 of 1, false of true) accepteert. Het resultaat hiervan is alleen true (of 1) als beide bits true (1) zijn. Kijk nu nog eens naar deze som:
Dit is een simpele rekensom, maar enkel met de cijfers 0 en 1 en een ander wiskundig symbool.
ik zit me nu in te lezen, ik moet gewoon helemaal bij het begin beginnen
ik leer nu alles over cijfertjes :)
http://code.tutsplus.com/tutorials/number-systems-an-introduction-to-binary-hexadecimal-and-more--active-10848
en als ik dat doorgeploegd heb, ga ik weer terug naar het hoofdstuk bitwise misschien snap ik het dan wel
Thomas van den Heuvel:
Jawel.
Stel:
zwart = 1
wit = 2
rood = 4
beige = 8
Wat je wilt is zwart + wit + rood = 7.
De kat met zwart + wit + rood + beige = 15.
Stel:
zwart = 1
wit = 2
rood = 4
beige = 8
Wat je wilt is zwart + wit + rood = 7.
De kat met zwart + wit + rood + beige = 15.
want 7 = 2<sup>3</sup>2<sup>2</sup>2<sup>1</sup>2<sup>0</sup>
0 1 1 1
15 = 2<sup>3</sup>2<sup>2</sup>2<sup>1</sup>2<sup>0</sup>
1 1 1 1
& ----------------------------------------------------------
0 1 1 1
Thomas van den Heuvel:
15 & 7 is nog steeds 7. Oftewel, de selectie zwart + wit + rood levert ook beesten met zwart + wit + rood + whatever op.
15 & 7 is nog steeds 7. Oftewel, de selectie zwart + wit + rood levert ook beesten met zwart + wit + rood + whatever op.
Ik heb er een week over gedaan, maar nu snap ik dat 15 ook 7 is.
Alleen nog niet helemaal hoe ik dat kan selecteren, maar misschien komt dat nog
Gewijzigd op 27/02/2016 23:51:55 door marina janssen
Quote:
Alleen nog niet helemaal hoe ik dat kan selecteren, maar misschien komt dat nog
Selectboxes kleuren[] maken met als waarde de unieke kleurcode, en dan, als je je zoekformulier submit (gebruikt $_GET, dat werkt doorgaans fijner) kijk je of "kleuren" ($_GET['kleuren'] dus) bestaat en tel je de waarden bij elkaar op met array_sum($_GET['kleuren'). Zoals eerder aangegeven kun je elke kleur uniek identificeren omdat elke kleurcode een waarde heeft die een macht van 2 is (1, 2, 4, 8, 16 etc.).
De kleurcode wordt wel uitgelezen (opgeteld) uit de url. Ik doe precies hetzelfde als op andere pagina;s maar ik krijg array_sum() expects parameter 1 to be array als ik naar blz 2 (of verder) blader. heelp
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<form action="..." method="get">
...
<input type="checkbox" name="kleuren[]" id="kleuren_1" value="1"><label for="kleuren_1">zwart</label>
<input type="checkbox" name="kleuren[]" id="kleuren_2" value="2"><label for="kleuren_2">rood</label>
<input type="checkbox" name="kleuren[]" id="kleuren_4" value="4"><label for="kleuren_4">wit</label>
<input type="checkbox" name="kleuren[]" id="kleuren_8" value="8"><label for="kleuren_8">beige</label>
...
<button type="submit">zoek</button>
</form>
...
<input type="checkbox" name="kleuren[]" id="kleuren_1" value="1"><label for="kleuren_1">zwart</label>
<input type="checkbox" name="kleuren[]" id="kleuren_2" value="2"><label for="kleuren_2">rood</label>
<input type="checkbox" name="kleuren[]" id="kleuren_4" value="4"><label for="kleuren_4">wit</label>
<input type="checkbox" name="kleuren[]" id="kleuren_8" value="8"><label for="kleuren_8">beige</label>
...
<button type="submit">zoek</button>
</form>
Dan komt dit op de volgende manier in je URL:
zoekscript.php?kleuren[]=1&kleuren[]=4&...
Je moet dan wel zorgen dat je alles op een of andere manier overneemt als er iets is aangevinkt.
Denk eraan dat niet aangevinkte checkboxen in het geheel niet worden verstuurd, je zult dus op het bestaan van $_GET['kleuren'] (of $_POST['kleuren'] als je de POST method gebruikt) moeten controleren.
Stel ik vink grijs en wit aan. (wit= 1 en grijs =2)
Dan is de url van blz 1: kleurcodes.php?Code[]=1&Code[]=2
Maar als ik naar blz. 2 ga, (nog steeds zelfde checkboxes dus) dan is de url: kleurcodes.php?Code=3&page=2
Vraag 1: Ik snap niet waarom hij op blz 1 de ingevoerde codes exact weergeeft als Code[]=1&Code[]=2 in de url maar ze optelt als ik naar pag 2 ga. Want ik stop $Code in de query en de var_dump daarvan is 3 (op blz. 1).
Code (php)
Vraag 2:
Hoe krijg ik Code[]=1&Code[]=2 in de url op blz 2 ipv Code=3
Vraag 3:
Waarom blijft mn query eigenlijk leeg op blz 2 bij Code=3? De Code is 3! Ben ik nou gek???
Vragen, vragen vragen ...
Marina janssen op 29/02/2016 23:45:23:
Dat doe je toch echt zelf, want je telt 1 + 2 op met array_sum():Dan is de url van blz 1: kleurcodes.php?Code[]=1&Code[]=2
Maar als ik naar blz. 2 ga, (nog steeds zelfde checkboxes dus) dan is de url: kleurcodes.php?Code=3&page=2
Vraag 1: Ik snap niet waarom hij op blz 1 de ingevoerde codes exact weergeeft als Code[]=1&Code[]=2 in de url maar ze optelt als ik naar pag 2 ga. Want ik stop $Code in de query en de var_dump daarvan is 3 (op blz. 1).
Maar als ik naar blz. 2 ga, (nog steeds zelfde checkboxes dus) dan is de url: kleurcodes.php?Code=3&page=2
Vraag 1: Ik snap niet waarom hij op blz 1 de ingevoerde codes exact weergeeft als Code[]=1&Code[]=2 in de url maar ze optelt als ik naar pag 2 ga. Want ik stop $Code in de query en de var_dump daarvan is 3 (op blz. 1).
Code (php)
Als je toch gaat pagineren, waarom sla je de keuzen van pagina 1 dan niet even op in een sessie voordat je pagina 2 toont?
Quote:
Als je toch gaat pagineren, waarom sla je de keuzen van pagina 1 dan niet even op in een sessie voordat je pagina 2 toont?
Omdat het een zoekformulier is. Waarbij je een resultaat op deze manier makkelijk kunt bookmarken. Je hebt dan precies alle data die je nodig hebt in je URL. Je hebt dan geen externe hulpstukken in de vorm van een sessie nodig. Deze oplossing is stateless (of iig "self contained").
vraag 2: URL opbouwen / uitschrijven; plak voor elke geselecteerde kleurcode <separator>code[]=<kleurcode> vast aan de querystring. Waarbij <separator> ofwel een ? is, of een & en <kleurcode> de geselecteerde kleurcode, dit kan met een eenvoudig loopje die $_GET['Code'] doorloopt, nadat je hebt gecontroleerd of $_GET['Code'] bestaat.
vraag 3: waarschijnlijk omdat $_GET['Code'] op dat moment geen array meer is. Het resultaat van array_sum($_GET['Code']) levert op dat moment niks op (of liever gezegd NULL, wat mogelijk nog omgezet wordt naar het cijfer 0). Dit produceert tevens een warning. Je zou altijd moeten ontwikkelen met het ingeschakeld zijn van het melden + weergeven van fouten. Zet de bovenstaande code aan het begin van scripts waar je aan ontwikkelt:
Dan worden dit soort fouten meteen evident.
Maar ik snap een ding nog niet helemaal mbt het selecteren.
Als ik bijv. rood en wit invul in het formulier en opvraag met select, dan krijg ik alleen de katten die daar exact aan voldoen. Dus de katten die rood/wit zijn en de katten die wit/rood zijn.
Op zich kan ik daar prima mee leven maarrrrr je zei ergens dat de rood/wit/zwarte katten er dan ook uit zouden rollen maar dat gebeurt niet. Dus de vraag is: heb ik iets niet goed begrepen of niet goed uitgevoerd?
dit is mn query
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if(isset($_GET['Code'])) { $Code = array_sum($_GET['Code']);
$sql = "SELECT Nummer FROM katten WHERE Code = $Code";
$records = mysqli_query($conn, $sql);
$rows = mysqli_num_rows($records);
$pages = ceil($rows / $perpage);
$rec = "SELECT Nummer, Naam, Kleur, Geslacht, Vacht, Ras, Bijzonderheden, DATE_FORMAT(Datum,'%d/%m') AS Datum, FROM katten WHERE Code ='$Code' ORDER BY Nummer_id DESC LIMIT $start, $perpage";
$result = mysqli_query($conn, $rec);
etc etc
?>
if(isset($_GET['Code'])) { $Code = array_sum($_GET['Code']);
$sql = "SELECT Nummer FROM katten WHERE Code = $Code";
$records = mysqli_query($conn, $sql);
$rows = mysqli_num_rows($records);
$pages = ceil($rows / $perpage);
$rec = "SELECT Nummer, Naam, Kleur, Geslacht, Vacht, Ras, Bijzonderheden, DATE_FORMAT(Datum,'%d/%m') AS Datum, FROM katten WHERE Code ='$Code' ORDER BY Nummer_id DESC LIMIT $start, $perpage";
$result = mysqli_query($conn, $rec);
etc etc
?>
Gewijzigd op 06/03/2016 23:27:32 door marina janssen