8721 sujets

Développement web côté serveur, CMS

Bonjour,

Je cherche à faire une recherche dans plusieurs tables de ma base de données.

Dans ma base de données, j'ai trois tables (entre autre) :
- article (id, created, updated, titre, accroche, contenu...)
- partenaire (id, created, updated, nom, metier, contenu_bio, contenu_projet...)
- ouvrage (id, created, updated, titre, accroche, prix, couverture...)

Quand j'arrive sur ma page recherche, j'aimerais que ma recherche se fasse dans toutes les tables et qu'il m'affiche tous les contenus ordonnées par created.

Est-ce que quelqu'un aurait une solution ?

Merci d'avance !
Bonjour Zelena

Je suis déjà tombé sur cet article en cherchant. Mais comment afficher mes données ?
Pour l'instant je n'y arrive pas, voici mon code :
(ma base de donnée marche)

$bancal = $db->prepare('SELECT * FROM article LEFT JOIN categories ON article.category_id = categories.id_categorie 
                        UNION
                        SELECT * FROM partenaire 
                        UNION
                        SELECT * FROM ouvrages ORDER BY created DESC');
$bancal->execute();



et le code à l'intérieur de ma page :

<section class="col-7 marg-1">
                        <?php
                        $a=1;
                        while($data = $bancal->fetch(PDO::FETCH_ASSOC)){ 
                             if(is_int(($a+1)/2))
                        echo'<div class="row marge-bas">'; 
                            if(isset($data['article.category_id'])){?>
                            <article class="bloc-article col-6">
                                <a href="article.php?id=<?= $data['article.id'] ?>">
                                    <p class="categorie"><?= $data['nom_categorie'] ?></p>
                                    <figure><img src="data/article/en_avant/<?= $data['article.image_avant'] ?>"/></figure>
                                    <div class="contenu-article">
                                        <p class="date-article"><?= dateEU($data['article.created']) ?></p>
                                        <p class="titre-article"><?= $data['article.titre'] ?></p>
                                        <p class="accroche-article"><?= $data['article.accroche'] ?></p>
                                        <p><?php 
                                            $mot = explode(";", $data['article.mots_cles']);
                                            $nbmot = count($mot);
                                            for($i=0; $i<$nbmot; $i++){?>
                                                <span class="mot-cle"><?php echo $mot[$i]; ?></span>
                                            <?php } ?> </p>
                                    </div>
                                </a>
                            </article>
                        <?php 
                            }
                        if(isset($data['partenaire.name'])){?>
                            <article class="bloc-article col-6">
                                <a href="partenaire.php?id=<?= $data['partenaire.id'] ?>">
                                    <figure>
                                        <img class="redimension" src="data/partenaire/en_avant/<?= $data['partenaire.image_avant'] ?>"/></figure>
                                    <div class="contenu-article">
                                        <p class="nom-partenaire"><?= $data['partenaire.name'] ?></p>
                                        <p><?php 
                                            $mot = explode(";", $data['partenaire.metier']);
                                            $nbmot = count($mot);
                                            for($i=0; $i<$nbmot; $i++){?>
                                                <span class="mot-cle"><?php echo $mot[$i]; ?></span>
                                        <?php } ?>  </p>
                                    </div>
                                </a>
                            </article>
                        <?php 
                            } 
                        
                        if(isset($data['ouvrages.auteur'])){?>
                            <article class="bloc-article col-6 contenu-ouvrage">
                                <a href="ouvrage.php">
                                <figure class="align-bloc">
                                    <img class="img-bloc-image" src="data/ouvrage/couv/<?= $data['ouvrages.image_avant'] ?>"/>
                                </figure>
                                <div class="align-bloc decal-droite">
                                    <h1 class="titre-article"><?= $data['ouvrages.titre'] ?></h1>
                                    <p class="auteur-ouvrage"><?= $data['ouvrages.auteur'] ?></p>
                                    <p class="date-article"><?= dateEU($data['ouvrages.date_ouvrage']) ?></p>
                                    <p class="prix">Broché : <?= $data['ouvrages.broche']; 
                                        if(isset($data['ouvrages.epub'])){?>
                                            <br>E-Pub : '<?= $data['ouvrages.epub']; } ?></p>
                                </div>
                                <div>
                                    <p class="accroche-article"><?= $data['ouvrages.accroche'] ?></p>
                                </div>
                                </a>
                            </article>
                        
                        <?php 
                            }
                        if(is_int($a/2))
                            echo'</div>'; 
                        $a++;
                        } ?>
                    </section>
Il y a une jointure aussi ? Ça, c'est plus délicat.

D'abord, ce n'est pas la peine d'utiliser une requête préparée puisqu'il n'y a pas de variables dans votre code Php. La méthode query suffit.

Mais est-ce que c'est ce que vous voulez ? Quand on fait des recherches, on utilise des variables… Smiley confus

Pour le reste, je n'ai jamais utilisé UNION avec une jointure. Mais d'après ce qui est contenu dans le lien que j'ai envoyé, le nombre de colonnes de chaque requête doit être le même…

Vous devriez tester vos requêtes SQL à part, sans PHP pour voir si elles fonctionnent.

Smiley smile
Je voulais d'abord insérer mes éléments dans ma page et ensuite gérer la variable de recherche.

En testant de la manière la plus simple et avec ma variable de recherche, c'est bien cette requête que je dois faire ?

SELECT * FROM article WHERE * = :s
UNION
SELECT * FROM partenaire WHERE * = :s
UNION
SELECT * FROM ouvrages WHERE * = :s

Modifié par Lotte97 (22 Jun 2017 - 10:30)
Je pense que oui parce que d'après ce que j'ai compris UNION ne fait qu'ajouter des résultats contrairement aux jointures qui créent des tables virtuelles temporaires.

Mais rien ne vous empêche d'expérimenter en utilisant PhpMyAdmin ou une console. Utiliser PHP et PDO ne fait que rajouter une couche de complexité : il vaut mieux être sûr de ses requêtes d'abord.

Smiley smile
Modérateur
Mais si tu souhaites faire des UNION sur des tables qui n'ont pas les même colonnes ça ne va pas marcher à moins de bricoler:


 table1 | table2
-----------------
   id   |   id
  name  |  name
  prix  |  date
couleur |

SELECT id, name, prix, couleur, NULL as date FROM table1
UNION
SELECT id, name, NULL as prix, NULL as couleur, date FROM table2
@kustolovic super merci !

est-ce que tu saurais comment ordonné ta requête par ordre alphabétique de tous tes titres ?
J'ai testé un ORDER BY mais il me mets d'abord tous les élément d'une table, puis de l'autre table, alors que j'aimerais que tout soit mélangé
Modérateur
Il faut appliquer l'ORDER BY à la fin sur la dernière requête pour que ça s'applique à l'ensemble, pour reprendre mon exemple:


SELECT id, name, prix, couleur, NULL as date FROM table1
UNION
SELECT id, name, NULL as prix, NULL as couleur, date FROM table2
ORDER BY name
Pourquoi ne pas simplement faire 3 requêtes séparées ?

Si tu veux ensuite ordonner par created, tu peux faire un array_merge de tes 3 résultats de requêtes. Puis tu appliques un "sort" sur la clé created.