Page 1 sur 1

insérer Array dans requete mysql WHERE ... IN ou NOT IN

Posté : 15 mai 2008, 04:06
par Patriboom
Bonjour!

Ma question en est une de traitement PHP des résultats obtenus par une requête MySQL. J'ai de très grosses requêtes à gérer, tant et si bien que je dois les séparer. Les séparant, je passe de 12 secondes de traitement à 2. L'inclusion n'est donc pas une bonne solution.

Voici donc ma question: comment exploiter le résultat obtenu par la première requête le plus simplement possible?

Voici où j'en suis (avec des requêtes abrégées) :
//Première requête:
$requete1 = "SELECT * FROM personnes WHERE série_de_criteres";
$resultat1 = msyql_query($requete1, $db);

//Ici, je récupère les résultats pour en faire une liste
$Liste = "0, ";
while ($Details1 = mysql_fetch_object($resultat1)) {
     $Liste .= $Details1->id->personne.", ";
}

//La liste est insérée dans la seconde requête
[php]$requete2 = "SELECT * FROM inscrits WHERE NOT IN ( ".$Liste." )";
$resultat1 = msyql_query($requete1, $db);
blababla
[/php]
Les détails du code et des bases importent peu. Ce que je cherche, c'est de sauter l'étape de construction de la liste.



N'y a-t-il pas une fonction du style "explode" ou devrais-je utiliser mysql_fetch_array (et comment) ou que me proposez-vous pour simplifier la chose? Je trouve étonnant de ne pouvoir exploiter directement un tableau dans une fonction qui demande un tableau. :!: Il me semble que le processus serait plus léger et plus rapide si je pouvais avoir une seconde requête qui serait du style de :
$requete2 = "SELECT * FROM inscrits WHERE NOT IN ( ".explode($resultat1)." )";
Je n'y arrive pas.

Merci de votre aide.

Posté : 15 mai 2008, 08:08
par Calimero
Bonjour,

Un coup de pouce en deux questions :

- explode() transforme une chaîne en tableau (en la cassant selon un délimiteur), est-ce bien ce que tu veux faire ici ? :-)
- Indépendamment de la réponse à la question ci-dessus, où est passé le délimiteur :?:

Posté : 15 mai 2008, 09:28
par d0m
salut,

tu y étais presque...
Ce n'est pas explode qu'il faut utiliser mais son inverse : la fonction implode

Regarde bien la doc de ces 2 fonction et les exemples et tu comprendras leur fonctionnement.

Posté : 15 mai 2008, 09:28
par Hywan
Hey :),

Juste une remarque en passant. Tu as écrit :

Code : Tout sélectionner

SELECT * FROM table WHERE NOT IN ( ... );
Ce ne serait pas plutôt

Code : Tout sélectionner

SELECT * FROM table WHERE field NOT INT ( ... );
normalement ?

Et je pense que ton résultat peut s'obtenir en écrivant une sous-requête, ce serait plus simple et beaucoup plus rapide :

Code : Tout sélectionner

SELECT * FROM table WHERE field NOT INT ( SELECT field FROM table WHERE ... );

Posté : 15 mai 2008, 09:33
par naholyr
Le plus facile à utiliser, ce serait une fonction qui transforme une valeur PHP en son équivalent MySQL (avec les guillemets autour s'il s'agit d'une chaine, correctement échappé, les valeurs séparées par des virgules s'il s'agit d'un array, etc...).

cf. ma fonction SQL::escape()

Posté : 15 mai 2008, 14:56
par Patriboom
Merci pour vos réponses.
Pour l'instant, ça ne fonctionne pas encore.
Voici mon code réel:
$requPERS2 .= "AND PERS.id_perso IN ( "; 
$requPERS2a  = "SELECT id_perso ";
$requPERS2a .= "FROM paroisses_inscriptions AS INSCR3 ";
$requPERS2a .= "LEFT JOIN paroisses_agenda AS ACTI3 ON ACTI3.acti_id = INSCR3.id_acti ";
$requPERS2a .= "WHERE INSCR3.Complete = 'oui' AND ACTI3.acti_categ = ".$_POST["NumCatech"]." ";
$requPERS2a .= "GROUP BY INSCR3.id_perso ";
$requPERS2a .= "HAVING COUNT( id_perso ) ".$_POST["Oper1"]." ".intval($_POST["Blocs"]);
$resuPERS2a = mysql_query($requPERS2a, $db);
$requPERS2 .= implode(",", mysql_fetch_array($resuPERS2a ));
//WHILE ($QuelPERS2a = mysql_fetch_object($resuPERS2a )) {
//	$requPERS2 .= $QuelPERS2a->id_perso.', ';
//}
//$requPERS2 .= " 0) "; 
$requPERS2 .= "  ) ";
print 'Voici l`état de la requête: '.$requPERS2.'<br>';
J'ai laissé en remarque les quelques lignes qui me servent à donner un résultat ressemblant à ceci:
Voici l`état de la requête: AND PERS.id_perso IN ( 1, 151, 228, 303, 318, 346, 351, 367, 369, 381, 401, 453, 454, 459, 461, 468, 471, 604, 635, 645, 656, 680, 681, 806, 825, 860, 925, 983, 984, 1047, 1059, 1063, 1139, 1140, 1141, 4272, 0)
Mais pour l'instant, le résultat est celui-ci:
Voici l`état de la requête: AND PERS.id_perso IN ( 1,1 )
J'ai essayé avec mysql_fetch_object, _row, _array ... toujours la même chose.
J'ai regardé la fonction suggérée par naholyr, mais c'est plus compliqué que mes trois petites lignes. Je ne crois pas y sauver. Cependant, l'opérateur :: (quatre points) m'intrigue. J'ai investigué dans ce sens (section opérateurs du site documentation PHP ) sans arriver à trouver. Comment s'appelle cet opérateur? Pouvez-vous m'aiguiller vers des explication de ce code magique que je ne comprends pas?

Merci encore.

Posté : 15 mai 2008, 15:18
par Hywan
C'est l'opérateur de résolution de portée (ou Paamayim Nekudotayim). Il permet un accès au méthode statique par exemple, ou aux constantes d'une classe.

Posté : 15 mai 2008, 17:16
par vince_weed
Et je pense que ton résultat peut s'obtenir en écrivant une sous-requête, ce serait plus simple et beaucoup plus rapide :

Code : Tout sélectionner

SELECT * FROM table WHERE field NOT INT ( SELECT field FROM table WHERE ... );
C'est ce que je pensait aussi et aimerai savoir si cela ne fonctionne pas (ou plus probablement ne te convient pas), le pourquoi de la chose. A moins que le résultat intermédiaire te soit utile...

Posté : 15 mai 2008, 19:28
par Patriboom
Ce qui arrive c'est que le résultat intermédiaire est si gros qu'en sous-requête ça devient trop complexe. C'était ma première option. Depuis que j'ai séparé les choses, j'ai gagné du temps de réponse. Voilà pourquoi je cherche à garder cela séparé.

Posté : 15 mai 2008, 19:37
par Hywan
Je doute — personnellement hein — que ça ralentisse les choses de tout faire en SQL plutôt qu'en SQL/PHP. Le temps que les ressources SQL soient réécrites, envoyées à PHP, décodées par PHP, traitement dans la boucle, et retourne dans une requête, retraitement par SQL, et re-chemin inverse direction PHP, est assez conséquent.
Le traitement que tu fais dans la boucle ne me paraît pas si compliqué que ça à traduire en SQL, et crois-moi, tu gagneras en temps c'est sûr (en mémoire, c'est moins sûr, je ne saurais pas le quantifié comme ça, sans y réfléchir, mais ce serait négligeable face au temps).

Posté : 15 mai 2008, 23:31
par Sékiltoyai
C'est l'opérateur de résolution de portée (ou Paamayim Nekudotayim). Il permet un accès au méthode statique par exemple, ou aux constantes d'une classe.
Comment le mec il se la pète :)

Sinon je te plussoie. Le serveur SQL est optimisé, si tu peux tout faire dans une requète ce sera généralement beaucoup plus performant qu'en faisant le traitement par php…

Posté : 15 mai 2008, 23:38
par Hywan
C'est l'opérateur de résolution de portée (ou Paamayim Nekudotayim). Il permet un accès au méthode statique par exemple, ou aux constantes d'une classe.
Comment le mec il se la pète :)
Je l'ai copié du manuel … ^^. Je connais que 3 mots en hébreux et ce ne sont pas ceux-là haha.