Multiple Checkboxes sql query

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Orlando Smits

Orlando Smits

18/12/2013 14:20:48
Quote Anchor link
Hallo,

Met mijn opleiding ben ik bezig met een webshop met daarin de volgende vraag:
Ik en mijn groepsgenoten willen bij de categorie pagina meerdere categorieën kunnen filteren en dit in de sql query kunnen plaatsen.

Heeft iemand een idee hoe dit moet?
 
PHP hulp

PHP hulp

24/11/2024 14:12:06
 
Michael -

Michael -

18/12/2013 14:33:44
Quote Anchor link
Ik dacht aan zoiets
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
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    
    $sql = "SELECT FROM shop WHERE title LIKE '%" . $_POST['q'] . "%'";
    
    if(isset($_POST['cat'])){
        $i=0;
        foreach($_POST['cat'] AS $cat){            
            $sql .= ($i == 0) ? ' AND ' : ' OR ';
            $sql .= 'cat = "' . $cat . '"';
            $i++;
        }
    }

    
    echo $sql;
    /* Output: SELECT FROM shop WHERE title LIKE '%PHP%' AND cat = "boeken" OR cat = "cds" */
}
?>

<form method="POST">
<input type="search" name="q" /><br />
<label>Boeken</label>
<input type="checkbox" name="cat[]" value="boeken" />
<label>CD's</label>
<input type="checkbox" name="cat[]" value="cds" />
<label>Games</label>
<input type="checkbox" name="cat[]" value="games" />
<button>Zoeken</button>
</form>

Edit:
Kleine aanpassing in het script
Aanpassing betreft reactie van Erwin
Gewijzigd op 18/12/2013 15:05:39 door Michael -
 
Erwin H

Erwin H

18/12/2013 14:52:38
Quote Anchor link
Behalve dan dat je niet AND moet gebruiken in je query, maar OR. Anders kan je wel op "boeken" AND "games" zoeken, maar dan krijg je waarschijnlijk niet veel terug, aangezien het meestal een boek of game is.
Daarbij zou ik ook geen LIKE gebruiken, tenzij je erg onvoorstandig meerdere categorie opties in 1 databaseveld propt.
Correctie: de LIKE was voor de titel, niet voor de categorie.
Gewijzigd op 18/12/2013 14:53:42 door Erwin H
 
Michael -

Michael -

18/12/2013 15:06:19
Quote Anchor link
Erwin H op 18/12/2013 14:52:38:
Behalve dan dat je niet AND moet gebruiken in je query, maar OR. Anders kan je wel op "boeken" AND "games" zoeken, maar dan krijg je waarschijnlijk niet veel terug, aangezien het meestal een boek of game is.
Daarbij zou ik ook geen LIKE gebruiken, tenzij je erg onvoorstandig meerdere categorie opties in 1 databaseveld propt.
Correctie: de LIKE was voor de titel, niet voor de categorie.

Je hebt gelijkt. De eerste moet AND zijn, maar de daaropvolgende moet OR zijn. De code is hierop aangepast.
 
Orlando Smits

Orlando Smits

18/12/2013 15:25:50
Quote Anchor link
Bedankt voor de reactie, de checkboxes werken nu. Maar het probleem is dat producten die in meerdere categorieën plaats vinden niet meer getoond worden als er twee categorieën worden aangeklikt.
Dus bijvoorbeeld een flesje water die in de kerst en in de zomer verkocht kan worden, wordt niet getoond. Dus niet alle andere producten die of alleen in de zomer of alleen in de kerst worden getoond.
Gewijzigd op 18/12/2013 15:27:27 door Orlando Smits
 
Phpnuke r

phpnuke r

18/12/2013 15:29:08
Quote Anchor link
Is het geen optie om voor elke checkbox die er is een query uit te voeren? Zou met behulp van een loopje vrij weinig code moeten zijn (over snelheid ga ik niet spreken)
 
Michael -

Michael -

18/12/2013 15:30:34
Quote Anchor link
Je hebt een database met drinken en wilt filteren op zomer en winter? Als het goed is moet dat prima werken. Heb je de laatste wijziging met AND OR gebruikt (Zie reactie Erwin)?
Laat anders wat relevante code zien.
 
Orlando Smits

Orlando Smits

18/12/2013 15:35:23
Quote Anchor link
SELECT `product`.`product_id` , `product`.`naam` , `product`.`prijs` , `product`.`omschrijving` , `product`.`voorraad`
FROM `product` , `categorie` , `categorie_product`
WHERE `product` . `product_id` = `categorie_product`. `product_id`
AND `categorie`.`categorie_id` = `categorie_product`.`categorie_id`
AND `categorie`.`naam` = 'Zomer'
AND `categorie`.`naam` = 'Winter'

Tabellen:
Product (staan producten in)
Categorie (staan de categorieen in)
categorie_product (koppeltabel voor product en categorie)
 
Michael -

Michael -

18/12/2013 15:38:34
Quote Anchor link
Orlando Smits op 18/12/2013 15:35:23:

SELECT `product`.`product_id` , `product`.`naam` , `product`.`prijs` , `product`.`omschrijving` , `product`.`voorraad`
FROM `product` , `categorie` , `categorie_product`
WHERE `product` . `product_id` = `categorie_product`. `product_id`
AND `categorie`.`categorie_id` = `categorie_product`.`categorie_id`
AND `categorie`.`naam` = 'Zomer'
AND `categorie`.`naam` = 'Winter'

Tabellen:
Product (staan producten in)
Categorie (staan de categorieën in)
categorie_product (koppeltabel voor product en categorie)

Je hebt nu zomer AND winter, dus alle resultaten die in beide categorieën voorkomen.
Wil je dus ook producten die maar in 1 van de 2 categorieën voorkomt moet je de laatste wijzigen in OR.

WHERE `product` . `product_id` = `categorie_product`. `product_id`
AND `categorie`.`categorie_id` = `categorie_product`.`categorie_id`
AND `categorie`.`naam` = 'Zomer'
OR `categorie`.`naam` = 'Winter'

Edit:
Beter is denk ik nog om zomer en winter tussen haakjes te plaatsen

AND (`categorie`.`naam` = 'Zomer'
OR `categorie`.`naam` = 'Winter')
Gewijzigd op 18/12/2013 15:42:02 door Michael -
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

18/12/2013 15:42:36
Quote Anchor link
De vraag is hoe het opgeslagen wordt in database.
Dit lijkt mij een typisch voorbeeld van een meer op meer relatie, en dus zou er een linktabel moeten bestaan om de producten aan meerdere categorieën te kunnen koppelen.

Overigens is het een stuk eenvoudiger om WHERE ... IN te gebruiken dan elke keer ... = ... OR ... = ... te doen.
 
Erwin H

Erwin H

18/12/2013 15:54:06
Quote Anchor link
Zo te zien is er dus al normalisatie ten aanzien van de categorieen (heel goed overigens), dus dan wordt het een heel ander verhaal. Ten eerste moet je dan bepalen of een product dat aan 1 categorie voldoet moet worden gekozen, of alleen als het aan allen voldoet. Ten tweede zal je dan de rijen moeten gaan tellen.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
SELECT a.product_id, a.naam, a.prijs, a.omschrijving, a.voorraad
FROM product a
LEFT JOIN categorie_product b ON a.product_id = b.product_id
LEFT JOIN categorie c ON b.categorie_id = c.categorie_id
WHERE c.naam IN ('zomer', 'winter')
GROUP BY a.product_id, a.naam, a.prijs, a.omschrijving, a.voorraad
HAVING COUNT(*) = 2;

Als je de having clause op 2 zet krijg je alleen de resultaten die aan alle categorieen voldoen, zet je het op >= 1 dan krijg je alle die 1 of meer hebben.
Gewijzigd op 18/12/2013 15:58:06 door Erwin H
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

18/12/2013 15:56:03
Quote Anchor link
Als je ipv de categorie naam de id in de value van de checkbox kan je de categorie tabel buiten beschouwing laten.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
$sql
= "SELECT product_id, p.product_name, p.product_price
    FROM product p
    JOIN categorie_product c USING (product_id)
    WHERE c.categorie_id IN ("
. implode(',', $_POST['categorie'] . ')';
?>
 
Erwin H

Erwin H

18/12/2013 15:57:10
Quote Anchor link
Ger, merk wel op dat je zo resultaten dubbel kunt krijgen.
 
Orlando Smits

Orlando Smits

18/12/2013 15:59:30
Quote Anchor link
We hebben hem nu zo opgelost. Zo komen de producten tevoorschijn bij de categorieën.

SELECT `product`.`product_id` , `product`.`naam` , `product`.`prijs` , `product`.`omschrijving` , `product`.`voorraad`
FROM `product` , `categorie` , `categorie_product`
WHERE `categorie`.`naam` IN ('Zomer', 'winter')
AND `product` . `product_id` = `categorie_product`. `product_product_id`
AND`categorie`.`categorie_id` = `categorie_product`.`categorie_categorie_id`
GROUP BY naam

En natuurlijk iedereen bedankt voor de hulp!
Gewijzigd op 18/12/2013 16:00:05 door Orlando Smits
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

18/12/2013 16:00:41
Quote Anchor link
Idd Erwin, was de DISTINCT vergeten
 
Erwin H

Erwin H

18/12/2013 16:01:54
Quote Anchor link
@Orlando: Weet wel dat je een foute GROUP BY clause hebt. Als je docent een pietje precies is zal hij je daarop aanspreken. In een GROUP BY moeten in principe alle non-aggregate kolommen uit de select. In jouw geval dus allemaal.
Gewijzigd op 18/12/2013 16:02:23 door Erwin H
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

18/12/2013 16:03:31
Quote Anchor link
@Orlando,
Je gebruikt group_by zonder aggegrate functie, dus heb je hem niet nodig, en het maakt de query alleen maar trager.
 
Orlando Smits

Orlando Smits

18/12/2013 16:05:00
Quote Anchor link
Erwin H op 18/12/2013 16:01:54:
@Orlando: Weet wel dat je een foute GROUP BY clause hebt. Als je docent een pietje precies is zal hij je daarop aanspreken. In een GROUP BY moeten in principe alle non-aggregate kolommen uit de select. In jouw geval dus allemaal.


Oke dan hebben we hem aangepast, Bedankt!
 



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.