[non résolu] mysql- rechercher dans plusieurs tables

mysql- rechercher dans plusieurs tables [non résolu] - SQL/NoSQL - Programmation

Marsh Posté le 21-04-2007 à 11:43:07    

Bonjour,
 
petite faiblesse après plus de 12 mois sans rien coder.
J'ai fait un petit script de recherche pas super élaboré, mais suffisant, mais qui... ne marche pas si je veux rechercher dans plusieurs tables à la fois.
exemple:
 
si je fais ça:

Code :
  1. $reponse = mysql_query('SELECT DISTINCT * FROM  thumbs_tab_ebo WHERE alt LIKE "%'.$motcle.'%" LIMIT '.$limite);


ça fonctionne.
 
 
mais si je fais ça:

Code :
  1. $reponse = mysql_query('SELECT DISTINCT * FROM  thumbs_tab_ebo, thumbs_tab_tin WHERE alt LIKE "%'.$motcle.'%" LIMIT '.$limite);


ça ne marche pas.
 
 
why?  :??:


Message édité par pmusa le 23-04-2007 à 20:14:02

---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 21-04-2007 à 11:43:07   

Reply

Marsh Posté le 21-04-2007 à 11:52:10    

les deux tables n'ont pas les mêmes champs ?
alors ça ne peux pas marcher...


---------------
Blog photo/récits activités en montagne http://planetcaravan.net
Reply

Marsh Posté le 21-04-2007 à 11:56:48    

ça ne marche pas SURTOUT si elles ont les mêmes champs.
 
1/ y'a pas de jointures explicite : le SGBD va donc te retourner un produit cartésien des deux tables
2/ si ALT est présent dans les deux tables, alors le SGBD ne sait pas sur quelle table effectuer le filtre, et provoque une erreur
 
 
Si les deux tables on RIGOUREUSEMENT la même structure tu peux faire ça :
 
select 'ebo' as tbl, *
from thumbs_tab_ebo
where alt like '%$motcle%'
union
select 'tin' as tbl, *
from thumbs_tab_tin
where alt like '%$motcle%'
 
=> Ainsi, tu fait le filtre comme désiré, et le champ 'tbl' te permet de savoir de quelle table vient l'info.

Reply

Marsh Posté le 21-04-2007 à 12:18:04    

oui, les 2 tab ont les mêmes champs. elles sont identiques sauf pour les entrées bien entendu.
 
alors j'ai essayé la requêt de MagicBuzz texto, à defaut de vraiment la comprendre:
 

Code :
  1. $reponse = mysql_query('
  2. select "ebo" as tbl, *
  3. from thumbs_tab_ebo
  4. where alt like "%'.$motcle.'%"
  5. union
  6. select "tin" as tbl, *
  7. from thumbs_tab_tin
  8. where alt like "%'.$motcle.'%"');
  9. $nb = mysql_num_rows($reponse);


 
affiche un err:

Code :
  1. Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in C:\Program Files\EasyPHP 2.0b1\www\inc\rechercher.php on line 23


 
 :??:  
 
en fait, par la suite, je reprends les resultats un peu comme suit:

Code :
  1. while ($donnees = mysql_fetch_array($reponse))
  2. {
  3.     // On écrit
  4.     echo '<a href="http://127.0.0.1/?o=dl&pwet=' . $donnees['redir'] . '" ><img src="' . $donnees['img'] . '" alt="' . $donnees['alt'] . '" title="' . $donnees['alt'] . '" /></a> ';
  5. }


 
 
 
 
 
 :(


Message édité par pmusa le 21-04-2007 à 12:22:08

---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 21-04-2007 à 12:26:11    

Déjà, en SQL, le séparateur, c'est ' et non ".
Donc change ton truc en :
 

Code :
  1. $reponse = mysql_query("select 'ebo' as tbl, * from thumbs_tab_ebo where alt like '%".$motcle."%' union select 'tin' as tbl, * from thumbs_tab_tinwhere alt like '%".$motcle."%'" );
  2. $nb = mysql_num_rows($reponse);


 
Sinon, si ça merde encore, remplace les * par la liste de tes champs.

Reply

Marsh Posté le 21-04-2007 à 12:27:26    

je dirai d'enlever les guillemets autour du nom des tables ?
 
grillé


Message édité par zecrazytux le 21-04-2007 à 12:27:56

---------------
Blog photo/récits activités en montagne http://planetcaravan.net
Reply

Marsh Posté le 21-04-2007 à 12:35:48    

oui pardon pour les quotes.   :pt1cable:  
 
ça marche je vous remercie. en tout cas c'est curieux qu'il faille nommer expressement les noms des champs à recuperer plutôt qu'un *, j'aurai jamais trouvé tout seul (d'habitude ça marche).  :sweat:  
 
 
 
résolu  :jap:


---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 21-04-2007 à 12:51:15    

Normal, pour plusieurs raisons :
- 'ebo' as table ne fait pas partie des champs de la table. Du coup, utiliser * ensuite pose un problème au SGBD : est-ce que l'étoile doit bien correspondre aux champs de la table ? Pour cette raison, nombre de SGBD n'acceptent pas de mélanger * avec des champs explicites
- le UNION nécessite extactement les mêmes champs dans chaque table. Plutôt que de se fier aux noms, qui peuvent être différents, il se fie à l'odre. Pour cette raison, le * peut retourner des champs dans un odre différent, et donc bloquer la match entre les champs des tables
 
Dans tous les cas, le "*" ne doit JAMAIS ETRE UTILISE pour autrechose que lors du débug, afin de voir toute la structure des données retournées. Il pose d'énormes problèmes de performances, est bloquant pour les oppérations de regroupement, et autres.
 
Exemples de problèmes liés aux * :
 
insert into historique select * from matable;
=> avec les deux tables qui ont la même structure.
=> Demain, tu ajoutes un champ à l'un ou à l'autre des deux tables, ou suite à un alter, les champs ne sont plus dans le même ordre... Ben proutch !
 
select * from documents
=> Afin de récupérer une liste de documents. Au départ, document contient un champ "path" avec le chemin d'accès aux documents. Chaque ligne ne fait donc que quelques octets de données. Maintenant, pour diverses raison (options de fulltext search par exemple) tu décide de stocker tes documents dans cette table, dans un nouveau champ "blob". Chaque ligne fait maintenant plusieurs Mo... Je te laisse imaginer ce que ça donne si tu t'amuses à fetcher toutes les lignes du résultat, surtout si tu ne te sert pas de ce nouveau champ !
 
Bref, le * est à banir systématiquement !

Reply

Marsh Posté le 23-04-2007 à 20:03:28    

euh... d'accord.  :lol:  
bon mysql faudrait vraiment que j'approfondisse un de ces quatre.  :whistle:  
 
en attendant, j'utilise ta requete, sur tes conseils avisés:
 

Code :
  1. $reponse = mysql_query("select 'ebo' as tbl, redir,img,alt from thumbs_tab_ebo where alt like '%".$motcle."%' union
  2.      select 'bj' as tbl, redir,img,alt from thumbs_tab_bj where alt like '%".$motcle."%' union
  3.      select 'mf' as tbl, redir,img,alt from thumbs_tab_mf where alt like '%".$motcle."%' union
  4.      select 'tin' as tbl, redir,img,alt from thumbs_tab_in where alt like '%".$motcle."%'" );


 
Pour terminer mon petit moteur de recherche, j'ai besoin de savoir depuis quelle table le résultat est issue. thumbs_tab_bj? thumbs_tab_mf? etc. bref, y'a t-il un moyen de retourner cette info?
 
merci encore  :jap:


---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 23-04-2007 à 20:28:59    

ben à quoi sert le champ "tbl" que je t'ai fait ajouter à ton avis :sarcastic:

Reply

Marsh Posté le 23-04-2007 à 20:28:59   

Reply

Marsh Posté le 23-04-2007 à 20:35:32    

très probablement à quelquechose mais la question ultime est de savoir comment récuperer ça.  :whistle:


---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 23-04-2007 à 20:47:59    

et bien tbl = ebo | bj | mf | tin


---------------
Blog photo/récits activités en montagne http://planetcaravan.net
Reply

Marsh Posté le 23-04-2007 à 20:51:10    

tu veux dire qu'il les retourne tel que:
 
tbl='ebo | bj | mf | tin';
 
?
 
un ptit explode(); et c'est bon?
 
désolé hein.  :D


---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 23-04-2007 à 21:10:20    

t'est désespérant xD
 
tbl = ebo si la table est thumbs_tab_ebo
     = bj          "            "      thumbs_tab_bj
 
etc


---------------
Blog photo/récits activités en montagne http://planetcaravan.net
Reply

Marsh Posté le 24-04-2007 à 09:20:39    

ben oui, t'as juste à lire ce qu'il y a dans "tbl" pour chaque ligne. et la valeur correspond à l'origine des données de la ligne

Reply

Marsh Posté le 25-04-2007 à 17:59:22    

ah ui anéfé.  :whistle:  
merci jeunesse.
 
tjrs dans la même lignée:
 
serait-il possible de faire une boucle sur cette requête via un array()?
 

Code :
  1. $reponse = mysql_query("select 'ebo' as tbl, redir,img,alt from thumbs_tab_ebo where alt like '%".$motcle."%' union
  2.      select 'bj' as tbl, redir,img,alt from thumbs_tab_bj where alt like '%".$motcle."%' union
  3.      select 'mf' as tbl, redir,img,alt from thumbs_tab_mf where alt like '%".$motcle."%' union
  4.      select 'tin' as tbl, redir,img,alt from thumbs_tab_tin where alt like '%".$motcle."%'" );


sachant que mon array est le suivant:

Code :
  1. $cats=('ebo','bj','mf','tin');


 
ça aurait pu etre de la rigolade mais le fait que celà soit un requete SQL et qu'il y a le mot union 3 fois au lieu de 4 complique la chose. :'(
 
 
Merci de nouveau les experts.  :D


---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 25-04-2007 à 19:36:48    

j'ai pas compris ta question...
tu veux trier les resultats dans un tableau ensuite ? tu n'as qu'a trié par le champs tbl


---------------
Blog photo/récits activités en montagne http://planetcaravan.net
Reply

Marsh Posté le 25-04-2007 à 20:21:38    

tu veux générer dynamiquement la requête c'est ça ?
 
regarde du côté des fonctionnalités de "merge" d'un array en PHP.

Reply

Marsh Posté le 25-04-2007 à 20:23:41    

non, en fait les nom de mes tables commencent tous par le préfixe thumbs_tab_ et les champs sont rigoureusement identiques. du coup, pour simplifier les chose, j'ai un fichier config qui contient le nom de tous les suffixes des tables:
$cats=('ebo','bj','mf','tin');
ce qui donnerai --> thumbs_tab_ebo, thumbs_tab_bj, etc
 
donc je voudrais me débrouiller pour faire un truc du genre ceci:

Code :
  1. for($i=0,$i < count($cats),$i++){
  2. mysql_query("select '".$cats[$i]."' as tbl, redir,img,alt from thumbs_tab_".$cats[$i]." where alt like '%".$motcle."%'" );
  3. }


 
mais en y incorporant le requete que j'ai posté precedemment.
 
sauf que avec les union, c'est pas évident vu que la dernière ligne de la requête (celle concernant thumbs_tab_tin par exemple dans mon post precedant) n'a pas le terme union donc je ne peux pas faire d'itération. :/
 
 
 
et en plus, dans un souci de souplesse, pouvoir faire ça via une boucle me permettrais de ne plus toucher au moteur de recherche si jamais j'ajoute une nouvelle table, par exemple thumbs_tab_pouet, bu que j'aurai juste à modifier mon array dans le fichier config --> $cats=('ebo','bj','mf','tin','pouet');  :love:


---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 25-04-2007 à 20:26:39    

donc, comme je disais :
Avant la boucle, déclare un array de la taille du nombre de tables.
Dans ta boucle, écrit dans ce array à la ligne "i", la requête telle que tu viens de l'écrire.
Après la boucle, récupère dans une string un "merge" sur ce array, en utilisant " union " comme séparateur.
 
Et le tour est joué.

Message cité 1 fois
Message édité par MagicBuzz le 25-04-2007 à 20:27:18
Reply

Marsh Posté le 25-04-2007 à 20:28:27    

PS : si tu multiplies de la sorte les tables, je te conseille vivement de revoir ton modèle, et n'utiliser qu'une unique table avec un champ "tbl" directement à l'intérieur... Ce sera 10 fois plus automatisé et bien plus simple (sans parler des performances qui seront accrues de façon exponentielles)

Reply

Marsh Posté le 25-04-2007 à 20:38:28    

MagicBuzz a écrit :

donc, comme je disais :
Avant la boucle, déclare un array de la taille du nombre de tables.
Dans ta boucle, écrit dans ce array à la ligne "i", la requête telle que tu viens de l'écrire.
Après la boucle, récupère dans une string un "merge" sur ce array, en utilisant " union " comme séparateur.
 
Et le tour est joué.


pas comprite. :'(
un peu de code chef?
 

MagicBuzz a écrit :

PS : si tu multiplies de la sorte les tables, je te conseille vivement de revoir ton modèle, et n'utiliser qu'une unique table avec un champ "tbl" directement à l'intérieur... Ce sera 10 fois plus automatisé et bien plus simple (sans parler des performances qui seront accrues de façon exponentielles)


trop tard.
ça m'obligerai à revoir une grosse partie de mon code et ça m'ennuie un peu. de toute façon mon projet n'est suffisament "sérieux" pour qui j'y prete autant d'attention. peut-être à l'avenir.


---------------
intralase surgery [:cerveau love]
Reply

Marsh Posté le 26-04-2007 à 09:47:36    

je peux pas te filer de code, parceque moi je sais pas faire de php :o
 
alors viens pas te plaindre si ça marche pas hein :o
 

Code :
  1. queries = new Array(count($cats));
  2. for ($i=0; $i < count($cats); $i++)
  3. {
  4.    queries[i] = "select '".$cats[$i]."' as tbl, redir,img,alt from thumbs_tab_".$cats[$i]." where alt like '%".$motcle."%'";
  5. }
  6. mysql_query(fonction_a_la_con_qui_merge(queries, " union " ));

Reply

Marsh Posté le 26-04-2007 à 11:24:49    

implode est ton ami :)
 
http://fr2.php.net/implode


---------------
Blog photo/récits activités en montagne http://planetcaravan.net
Reply

Marsh Posté le 26-04-2007 à 11:57:38    

exactement :)
 
donc "fonction_a_la_con_qui_merge" est à remplacer par "implode" en inversant l'ordre des paramètres :)

Reply

Marsh Posté le 27-04-2007 à 00:55:51    

Code :
  1. for ($i=0; $i < count($cats); $i++)
  2. {
  3.     $queries[$i] = "select '".$cats[$i]."' as tbl,redir,img,alt from thumbs_tab_".$cats[$i]." where alt like '%".$motcle."%'";
  4. }
  5. $reponse=mysql_query(implode(' union ',$queries));


ça marche tip top.  :)  
merci!  :jap:  :hello:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed