Obtenir toutes les entrées d'un tableau stocké dans une variable

Le IN, c'est cool, mais ça fait pas tout.

a marqué ce sujet comme résolu.

Bonjour :)

Je viens vers vous avec une petite question concernant une requête qui me pose problème, celle-ci fonctionne correctement, mais n'est pas assez sélective à mon goût. En effet, je souhaiterais que toutes les conditions soient "vraies" et non pas une seule d'entres-elles. Le IN permet de vérifier que telle OU telle condition est bien remplie, mais je voudrais que telle ET telle condition soient remplies… Je ne sais pas si je suis très claire dans mes explications ^^'

Un extrait de code devrait vous aider à comprendre ce que je souhaite faire :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php 
  $categories = $_POST['filterOpts'];
  $categories = implode(', ', $categories);
  $pdo = new PDO('mysql:host=localhost;dbname=dbname', 'root', 'root');
  $select = 'SELECT DISTINCT employees.nom,employees.prenom';
  $from = ' FROM employe';
  $where = " LEFT JOIN employees_categories AS ec ON employees.id = ec.employe_id WHERE ec.categories_id IN ($categories) ";
  $sql = $select . $from . $where;
  $statement = $pdo->prepare($sql);
  $statement->execute();
  $results = $statement->fetchAll(PDO::FETCH_ASSOC);
  $json = json_encode($results);
  echo($json);
?>

Le problème concerne le IN à la ligne 7, idéalement, si mes categories n'étaient pas contenues dans des variables, je pourrais faire des tests grâce à des &&, mais je ne vois pas comment faire… Peut-être avec un foreach ? Mais ça ne me semble pas être la meilleure solution…

Quelqu'un pourrait me guider vers la meilleure méthode à employer dans ce genre de situation ? :)

Merci d'avance !

Salut !

Désolé de ne pas avoir de réponse à ta question ma foi intéressante. Pour ma part, je serais aussi parti sur une boucle… mais ton message m'aura donné l'occasion de chercher un peu, et j'ai trouvé ceci, dont la réponse la plus plébiscitée me paraît intéressante. La seconde mène vers une discussion sur les différentes implémentations qui existent, si tu voulais les adapter et les tester.

Au final, l'une des solutions semble être quelque chose comme ça :

1
2
3
4
5
6
7
SELECT e.nom, e.prenom,
    FROM employees e
        INNER JOIN employees_categories ec
            ON e.id = ec.employe_id
    WHERE ec.category_id IN (5, 8, 9)
    GROUP BY e.nom, e.prenom
    HAVING count(distinct ec.categories_id) = 3

Les catégories dans le IN sont construites comme dans ton exemple, et le 3 est repris de la taille du tableau des catégories

+0 -0

Salut Ymox, merci pour ta réponse qui me donne déjà une idée de la manière de procéder… même si je dois mal m'y prendre, puisque même en récupérant le nombre d'élément de mon tableau avec un count(), le filtrage n'a pas l'air de fonctionner correctement : par exemple, lorsque j'utilise plusieurs catégories, dont certaines inutilisées, un résultat apparait tout de même, ou certains résultats n'apparaissent pas alors qu'ils le devraient lorsque plusieurs catégories sont sélectionnées…

Par contre, il semblerait que cela marche lorsque je ne sélectionne qu'une seule catégorie… Il y a surement quelque chose que j'ai dû mal comprendre ?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?php 
  $categories = $_POST['filterOpts'];
  $categories = implode(', ', $categories);
  $nombre_categorie = count($categories);
  $pdo = new PDO('mysql:host=localhost;dbname=dbname', 'root', 'root');
  $select = 'SELECT DISTINCT employe.nom,employe.prenom, employe.groupement_employeur';
  $from = ' FROM employe';
  $where = " LEFT JOIN employe_categories AS ec ON employe.id_employe = ec.employe_id WHERE ec.categories_id IN ($categories) GROUP BY employe.nom,employe.prenom, employe.groupement_employeur HAVING COUNT(DISTINCT ec.categories_id) = $nombre_categorie";
  $sql = $select . $from . $where;
  $statement = $pdo->prepare($sql);
  $statement->execute();
  $results = $statement->fetchAll(PDO::FETCH_ASSOC);
  $json = json_encode($results);
  echo($json);
?>

J'ai essayé de reproduire exactement la même organisation, mais je ne parviens toujours pas à faire fonctionner correctement mon script :(

Est-ce que vous voyez quelque chose qui cloche par rapport au code sur les différents sujets de stackoverflow ?

1
2
3
4
5
6
7
  $categories = $_POST['filterOpts'];
  $categories = implode(', ', $categories);
  $nombre_categorie = count($categories);
  $pdo = new PDO('mysql:host=localhost;dbname=dbname', 'root', 'root');
  $select = 'SELECT e.nom,e.prenom,e.groupement_employeur';
  $from = ' FROM employe e';
  $where = " INNER JOIN employe_categories ec ON e.id_employe = ec.employe_id WHERE ec.categories_id IN ($categories) GROUP BY e.nom,e.prenom,e.groupement_employeur HAVING COUNT(DISTINCT ec.categories_id) = $nombre_categorie";
+0 -0

Juste pour être sûr, tu pourrais nous donner une requête complète juste avant qu'elle soit exécutée ?

Sinon, en fait, pourquoi regrouper par noms et prénoms plutôt que directement par ID d'employé ? C'est rare qu'on ait des homonymes, mais ça existe… et l'ID est du coup la seule manière d'éviter ce genre de soucis.

Si jamais, vu que tu utilises PDO::prepare puis PDOStatement::execute, utilise un marqueur et passe la valeur à PDOStatement::execute  ;)

+0 -0

Ah, j'ai oublié de préciser que je pensais à un marqueur pour le nombre de résultats uniquement, oui  :honte:

Par contre, j'aimerais comprendre. L'utilisation de intval(), c'est pour s'assurer qu'on aura bien des entiers uniquement ?

Le hic, c'est que même si l'exemple que j'ai donné utilise des entiers, justement, rien ne nous dit que c'en est pour l'auteur du sujet, et du coup, s'il s'agissait de chaînes de caractères, il pourrait effectivement manquer les guillemets autour des valeurs…

+0 -0

Par contre, j'aimerais comprendre. L'utilisation de intval(), c'est pour s'assurer qu'on aura bien des entiers uniquement ?

oui car dans l'exemple ce sont des entiers.

Si on utilise des chaînes il aurait fallu remplacer 'intval' par [$bdd,'quote'].

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte