requête spéciale, je ne m'en sort pas.

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : requête spéciale, je ne m'en sort pas.

Re: requête spéciale, je ne m'en sort pas.

par Cyrano » 12 oct. 2011, 14:04

...tu m'a pousser a chercher par moi tout en m’orientant, ça m'a permis de comprendre ce que je faisait !
C'est l'idée ;)
... on ne fais pas de la même façon visiblement....
Absolument, et je préfère la mienne, c'est plus lisible :p

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 12 oct. 2011, 13:56

J'avais trouvé ! Nos posts se sont croisés ! Tout d'abord merci Cyrano, tu m'a pousser a chercher par moi tout en m’orientant, ça m'a permis de comprendre ce que je faisait !

Voici la requête souhaitée:
SELECT tag.tag_id,tag.tag_libelle,element.elt_id,element.elt_libelle FROM element
INNER JOIN element_has_tag
ON element_has_tag.elt_id = element.elt_id
INNER JOIN tag
ON tag.tag_id = element_has_tag.tag_id
WHERE element.elt_id=2
En fait le where doit venir après les jointures.... je l'avais placé partout sauf la.

Edit: on ne fais pas de la même façon visiblement....

Re: requête spéciale, je ne m'en sort pas.

par Cyrano » 12 oct. 2011, 13:51

Tu as trois tables, donc deux jointures : là, tu n'en fais qu'une seule. essaye comme ceci :
SELECT
  tag.tag_id,
  tag.tag_libelle,
  element.elt_id,
  element.elt_libelle
FROM tag
  INNER JOIN element_has_tag ON element_has_tag.tag_id = element.tag_id
  INNER JOIN element ON element_has_tag.elt_id = element.elt_id
Ne trouves-tu pas ça plus logique de cette manière ?

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 12 oct. 2011, 13:23

Y'a quelque chose que je ne comprend pas....

ceci

SELECT tag.tag_id, tag.tag_libelle, element.elt_id, element.elt_libelle
FROM tag,element
INNER JOIN element_has_tag ON element_has_tag.elt_id = element.elt_id


fonctionne, même si le résultat n'est pas celui que je veux.

et ceci

SELECT tag.tag_id, tag.tag_libelle, element.elt_id, element.elt_libelle
FROM tag,element
INNER JOIN element_has_tag ON element_has_tag.tag_id = tag.tag_id

ne fonctionne pas: Champ 'tag.tag_id' inconnu dans on clause

Par contre, si j'inverse tag et element dans mon FROM, le deuxieme code fonctionnera mais pas le premier...

Dans ma clause ON je ne peut tester que la deuxième table indiquée dans mon FROM.

Re: requête spéciale, je ne m'en sort pas.

par Cyrano » 12 oct. 2011, 12:30

ta jointure ne comporte qu'une clause de tri mais pas la clause de jointure elle-même entre les deux tables, donc tu obtiens un produit cartésien... en d'autres termes, il en manque un bout.

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 12 oct. 2011, 12:21

Tu parles bien de celui ci ? faq-tutoriels/les-jointures-niveau-debutant-t21507.html

Je l'ai lu et bien compris, le problème ici, c'est que j'ai un ID élément défini à la base et que je dois récupérer les informations de 2 tables (element et tag) liées par une troisième (element_has_tag).

C'est fou parce que j'arrive à te l'expliquer mais je n'arrive pas à le réaliser...

Re: requête spéciale, je ne m'en sort pas.

par Cyrano » 12 oct. 2011, 12:02

Tout juste : regarde dans la FAQ, il y a un tuto sur les bases fondamentales des jointures.

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 12 oct. 2011, 11:20

Aaaah ca avance dans la compréhension, j'ai enfin réussi une requête valable.
// Uniquement les tags utilisés
$sql="SELECT tag.tag_id,tag.tag_libelle FROM tag
		INNER JOIN element_has_tag 
		ON element_has_tag.tag_id = tag.tag_id
		GROUP BY tag.tag_id";
var_dump($sql);
$query = mysql_query($sql) or exit('Erreur SQL : '.mysql_error().' Ligne : '. __LINE__ .'.');
while($data = mysql_fetch_assoc($query)){;
	var_dump($data);
}
Ca me sort bien mes 3 tags et non le 4ème qui n'est pas utilisé.

Code : Tout sélectionner

array 'tag_id' => string '1' (length=1) 'tag_libelle' => string 'TestTag1' (length=8) array 'tag_id' => string '2' (length=1) 'tag_libelle' => string 'TestTag2' (length=8) array 'tag_id' => string '3' (length=1) 'tag_libelle' => string 'TestTag3' (length=8)
C'était la plus simple.

Maintenant la suivante. Ici j'ai un élément défini, et je dois récupérer l'id et le libelle de l'élément ainsi que l'id et le libellé de chaque tag lié a cet élément, donc je dois jouer sur 3 tables
// Uniquement les tags liés à un élément
$idElement = 2;
$sql="SELECT tag.tag_id,tag.tag_libelle,element.elt_id,element.elt_libelle FROM tag,element
		INNER JOIN element_has_tag
		ON element_has_tag.elt_id = $idElement ";
var_dump($sql);
$query = mysql_query($sql) or exit('Erreur SQL : '.mysql_error().' Ligne : '. __LINE__ .'.');
while($data = mysql_fetch_assoc($query)){;
	var_dump($data);
}
ici il me sort carrément 12 résultats alors qu'il devrait y'en avoir que 3.

Dans le select, j'ai bien ce que je dois récupéré, donc je suppose que mon problème se situe dans la jointure.

Re: requête spéciale, je ne m'en sort pas.

par Cyrano » 11 oct. 2011, 23:55

Insère un var_dump() de la requête entre sa définition et son exécution et observe ce qui s'affiche : si ça a l'air normal, copie la requête et teste la directement dans phpMyAdmin et vois quel résultat ça retourne.

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 11 oct. 2011, 23:30

Bon j'ai fais quelques tests, j'ai rempli mes tables manuellement, je comprend le principe mais la construction de la requête me pose problème.

j'ai créé un petit code de test reprenant le schéma exact de cyrano ci dessus.
$bd_nom_serveur='localhost';
$bd_login='root';
$bd_mot_de_passe='';
$bd_nom_bd='liaison';
mysql_connect($bd_nom_serveur, $bd_login, $bd_mot_de_passe);
mysql_select_db($bd_nom_bd);
mysql_query("set names 'utf8'");
$idElement = 1; //simule un id
$sql="SELECT * FROM element WHERE elt_id=$idElement
		INNER JOIN tag
			ON element.elt_id = tag.elt_id";
$query = mysql_query($sql) or exit('Erreur SQL : '.mysql_error().' Ligne : '. __LINE__ .'.');
while($data = mysql_fetch_assoc($query)){
	echo $data['id']."<br />";	
}
j'ai beau retourner la requête dans tout les sens, il m'affiche une erreur de syntaxe sur la requête.

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 11 oct. 2011, 17:47

Ok, je suis en InnoDB. Je préfère restrict dans ce cas. Voici la requête qui à été exécutée.
ALTER TABLE `element_has_tag` ADD FOREIGN KEY ( `elt_id` ) REFERENCES `liaison`.`element` (
`elt_id`
) ON DELETE RESTRICT ON UPDATE RESTRICT ;

ALTER TABLE `element_has_tag` ADD FOREIGN KEY ( `tag_id` ) REFERENCES `liaison`.`tag` (
`tag_id`
) ON DELETE RESTRICT ON UPDATE RESTRICT ;
Je pense maintenant pouvoir faire un brin de recherche pour comprendre comment appliquer tout cela a mon script. J'ai déja repéré quelques tutos sur le sujet.

Je te remercie.

Re: requête spéciale, je ne m'en sort pas.

par Cyrano » 11 oct. 2011, 17:33

Si tu utilises le moteur InnoDB, tu peux effectivement ajouter les contraintes de clé étrangères. Dans ce cas, si tu mets ON DELETE RESTRICT et ON UPDATE RESTRICT, il se passera que tu ne pourras pas supprimer un tag ou un élément s'il existe une relation : il faudra d'abord modifier ou supprimer la relation avant de toucher à l'élément ou au tag, enfin ça concerne surtout la suppression. Ça évite de laisser dans ta base des données orphelines.
Si tu utilises ON DELETE CASCADE, en supprimant un tag ou un élément, ça va automatiquement supprimer la relation qui va avec au cas o`<u il y en aurait une, mais attention, c'est un truc dangereux si on est pas très attentif, et en cas d'erreur de manipulation, on peut perdre des données qui seront irrécupérables.

Mais si tu utilise MyISAM, laisse tomber, ce ne sera pas pris en compte, tu devras donc assurer l'intégrité référentielle par programmation.

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 11 oct. 2011, 17:25

Ok j'ai compris !

Je me suis créé une nouvelle base, avec exactement ces 3 tables pour les tests. J'ai un peu cherché de mon coté pour créer cette liaison sous phpmyadmin.

Je rentre donc dans ma table element_has_tag et je clique sur "gerer des relations".

pour elt_id je met en 'relation interne' -> liaison.element.elt_id
pour tag_id je met -> liaison.tag.tag_id

J'ai aussi un choix 'Contrainte de clé étrangère' je dois y mettre quelque chose ? et colonne descriptive ?

Lorsque je selectionne quelque chose dans 'contrainte clé étrangère' j'ai les options 'on delete' et 'on update' qui s'affichent

Re: requête spéciale, je ne m'en sort pas.

par Cyrano » 11 oct. 2011, 16:41

Très sommairement :
+---------------------+       +-----------------+        +-------------+----+
| element             |       | element_has_tag |        | tag         |    |
+----------------+----+       +------------+----+        +-------------+----+
| elt_id         | PK |-------| elt_id     | PK |    ,---| tag_id      | PK |
| elt_libelle    |    |       | tag_id     | PK |---`    | tag_libelle |    |
+----------------+----+       +------------+----+        +-------------+----+
Voilà ;a quoi ressembleraient tes tables : la table element_has_tag a une clé primaire composée des deux colonnes elt_id et tag_id qui sont en même temps des clés étrangères correspondant aux clés primaires des deux autres tables.

Donc lorsqu'il doit y avoir un lien entre un élément et un tag, ça va correspondre à une ligne dans la table relationnelle. Et le fait que la clé soit composite fait que chaque paire est unique, donc tu pourras retrouver plusieurs fois le même elt_id dans la table, ou plusieurs fois le même tag_id, mais jamais plus d'une seule fois une faire elt_id + tag_id. Et si d'aventure tu voulais pouvoir justement avoir plusieurs fois cette paire, alors il faudrait introduire un troisième identifiant dans la table relationnelle et l'ajouter à la clé primaire.

Est-ce qu'à ce stade la logique commence à t'apparaître un peu ?

Re: requête spéciale, je ne m'en sort pas.

par Zahnzao » 11 oct. 2011, 15:58

Je venais d'éditer, tu as les infos sur le type de données dans mon post précédent. A noter que ce sont les IDs des tags et non les tags en texte.

Pour clarifier le tout, j'ai une page admin, qui n'est qu'une série de 3 formulaires. Le premier est juste un ajout de catégorie à la bdd. Le second, idem, ajout de tags. Ce ne sont que des champs textes, rien de tordus. Donc je crée mes tags à l'avance.

Le troisième formulaire ajoute des éléments, j'ai donc une liste déroulante à choix unique pour la catégorie, et des checkbox pour les tags.

Lors du traitement, je serialize() mon $_GET['tags'] et je l'inclus tel quel dans la BDD, c'est donc un varchar.

Concernant le reste de ton post, si je comprend bien, ce serai une table reprenant chaque ajout de tag avec en référence l'id de l'élément et l'id du tag. Donc si un élément contient 3 tags, il y'aurai 3 enregistrements dans cette table. C'est ca ?

J'aurai besoin d'éclaircissement sur ceci:
la clé primaire serait alors une clé composite , formée par les deux clés étrangères tag_id et elt_id
Une clé composite ?

Merci à toi.