Page 1 sur 1

Requete SELECT avec un WHERE récupérant plusieurs valeurs po

Posté : 18 févr. 2009, 10:16
par jay64
Bonjour,

Imaginons la requete toute simple suivante :

CREATE TABLE ...

Code : Tout sélectionner

SELECT * FROM Enfants WHERE Enfants.IdParent = ...
avec IDParent pouvant contenir plusieurs valeurs possibles.

En effet, j'ai un array contenant déjà une liste de IdParents dont j'ai besoin dans la requête ci-dessus mais je sais pas comment la terminer.

Merci de votre aide !

Posté : 18 févr. 2009, 11:05
par albat
$req_01 = "SELECT champ
           FROM   Enfants E
           WHERE  E.IdParent = ".$valeur1."
              OR  E.IdParent = ".$valeur2."
              OR  E.IdParent = ".$valeur3;
$req_02 = "SELECT champ
           FROM   Enfants E
           WHERE  E.IdParent IN (".$valeur1.", ".$valeur2.", ".$valeur3.")";
Deux recommandations :
- Pas de SELECT *
- La première écriture est plus optimisée que la deuxième

Posté : 18 févr. 2009, 13:00
par Albat90
Hummm Albat, je ne comprend pas pourquoi tu dis que la première écriture est plus optimisé que la deuxième...
J'ai toujours pensé l'inverse :shock:
Tu peux m'en dire plus sur celle ci?

Albat90 ;)

Posté : 18 févr. 2009, 14:02
par albat
Le IN est hyper vorace.

Posté : 18 févr. 2009, 14:22
par Albat90
Haha ok, je vois ce que tu veux dire, donc je pense qu'il ne faut l'utiliser seulement quand il est necessaire.

Exemple :

Code : Tout sélectionner

SELECT champ FROM table WHERE clé_etrangère IN (SELECT cle_primaire FROM table2 WHERE condition);

ou alors je l'ai utiliser comme ceci :
$num_etudiant = $_POST['et_choix'];
	$num_prof = $_POST['pr_choix'];
	$liste_etu = implode(', ',$num_etudiant);
	$attrib_sql = "UPDATE etudiant SET NUM_PROF = $num_prof WHERE NUM_ETUDIANT in ($liste_etu)";
	mysql_query($attrib_sql) or die('impossible d\'attribuer :'.mysql_error());
$_POST['et_choix] étant un tableau de clé primaire :)


merci :)

Albat90 ;)

Posté : 18 févr. 2009, 14:50
par jay64
merci les gars, je teste ça ce soir !

Perso, ce qui a l'air de me plaire le plus est ceci :

Code : Tout sélectionner

SELECT champ FROM table WHERE clé_etrangère IN (SELECT cle_primaire FROM table2 WHERE condition);
compte tenu que je ne connais pas le nombre de possibilté qui m'attend => voilà pourquoi le OR me plait moins !

Posté : 18 févr. 2009, 14:57
par albat
Dans la mesure du possible, mieux vaut utiliser les jointures
que les requêtes imbriquées, surtout reliées par un IN. :afraid:

Posté : 18 févr. 2009, 16:32
par Albat90
Donc Jay64, la meilleurs possibilité que tu as est peut être d'utiliser ceci :

Code : Tout sélectionner

SELECT champ FROM table, table2 WHERE table.cle_etrangere = table2.cleprimaire AND table2.champ = valeur
Cette requête correspond à celle du IN.

Si je me suis attacher au IN, c'est simplement que c'est plus cours à marquer sur papier lors des interrogations écrites :-k

Albat90 ;)

Posté : 18 févr. 2009, 17:11
par albat
Si je me suis attacher au IN, c'est simplement que c'est plus cours à marquer sur papier lors des interrogations écrites :-k
Et ton prof accepte ça ??? :shock:

Son nom ! Que je l'agonisse d'injures... :evil:


Rhââââ les Albat*, quels paresseux ! :lol:

Posté : 18 févr. 2009, 17:12
par jay64
alors là je ne suis plus, je ne comprends plus ta dernière requête ... :shock:

Rappelez-vous, je ne sais pas à l'avance combien de IdParents (tout dépend du cas de figure en question) je vais récupérer pour afficher tous mes NomEnfants ..

Posté : 18 févr. 2009, 17:33
par albat
alors là je ne suis plus, je ne comprends plus ta dernière requête ... :shock:
Ne panique pas, c'est notre faute : on a un peu élargi le sujet. :oops:

Si tes valeurs sont stockées dans une 2e table,
tu peux utiliser une requête à jointure sur le modèle de celle proposée par Albat90.

En revanche, si ces valeurs sont dans un tableau PHP ($tableau = array();),
dans ce cas, pas de requêtes imbriquées ni de jointures puisque tu n'utilises qu'une seule table.

Mais du coup, tu peux très bien compter le nombre de valeurs
en utilisant les fonctions count() ou sizeof(), qui sont identiques. ;)

Posté : 18 févr. 2009, 17:39
par Albat90
Si je me suis attacher au IN, c'est simplement que c'est plus cours à marquer sur papier lors des interrogations écrites :-k
Et ton prof accepte ça ??? :shock:

Son nom ! Que je l'agonisse d'injures... :evil:


Rhââââ les Albat*, quels paresseux ! :lol:
Oui oui, elle accepte ceci et sans soucis :shock:
Je t'aurais bien dis le nom mais c'est interdit non? En tout cas, c'est une femme :P
alors là je ne suis plus, je ne comprends plus ta dernière requête ... :shock:

Rappelez-vous, je ne sais pas à l'avance combien de IdParents (tout dépend du cas de figure en question) je vais récupérer pour afficher tous mes NomEnfants ..
On va prendre un exemple tout simple :

On a des élèves et des profs

Eleve(num_eleve, nom_eleve, prenom_eleve, num_prof#)
prof(num_prof, nom_prof, prenom_prof, ville_prof)

On veux afficher les tous les élèves des profs habitant Paris.

Tu as deux solutions :
La première, celle que Albat supprimerait de son code dans cette situation

Code : Tout sélectionner

SELECT nom_eleve, prenom_eleve FROM eleve WHERE num_prof (SELECT num_prof FROM prof WHERE ville_prof = "Paris");
Sinon tu as la deuxième solution beaucoup plus optimisée

Code : Tout sélectionner

SELECT nom_eleve, prenom_eleve FROM eleve, prof WHERE eleve.num_prof = prof.num_prof AND ville_prof = "Paris";
Les deux requêtes te renverrons le même résultat, cependant la deuxième sera plus rapide. Tu ne sentira pas la différences si tes tables ne contiennent pas beaucoup d'occurrences. Cependant, si celle ci en contienne d'avantage, je te laisse deviner la suite :)

Albat90 ;)

Posté : 18 févr. 2009, 19:59
par jay64
ah bien voilà, avec un bon exemple, tout est dessuite plus clair ! merci pour vos lumières les "alba's brothers" ...

c'est bien un tableau que j'ai concernant le $num_prof = array(), et c'est que je ne vous comprend plus pour savoir comment l'intégrer dans la condition de ma requete SELECT

Encore un petit coup de main s'il vous plait ... :? Merci !!!

Posté : 19 févr. 2009, 09:33
par Albat90
Hummm tu peux à la rigueur faire comme ceci mais je ne sais pas si c'est bien optimisé.
<?php
$tableau[0] = 1;
$tableau[1] = 3;
$tableau[2] = 4;
$tableau[3] = 8;
$tableau[4] = 11;
$tableau[5] = 13;
$tableau[6] = 15;
$tableau[7] = 18;
$tableau[8] = 21;
$tableau[9] = 24;

$nb = sizeof($tableau);
$requete = 'SELECT NOM_ENFANT FROM enfant WHERE IdParent = '.$tableau['0'].' ';
for($i=1; $i<$nb; $i++){
$requete = $requete.'AND IdParent = '.$tableau[$i].' ';
}
$requete = $requete.'ORDER BY NOM_ENFANT ASC';
echo $requete;
?>
Voici le résultat de cette page :
SELECT NOM_ENFANT
FROM enfant
WHERE IdParent = 1
AND IdParent = 3
AND IdParent = 4
AND IdParent = 8
AND IdParent = 11
AND IdParent = 13
AND IdParent = 15
AND IdParent = 18
AND IdParent = 21
AND IdParent = 24
ORDER BY NOM_ENFANT ASC

Il ne te reste plus qu'à faire un query sur ta $requete.
Le problème de cette solution est en effet si tu n'a pas de donnée dans ton array, il te fera une erreur à ta première affectation de $requete.

Mais cependant, tu peux toujours ajouter quelques vérifications pour éviter cela :)

Albat90 ;)

Posté : 19 févr. 2009, 13:17
par jay64
Merci beaucoup pour cette aide précieuse, c'est parfait !

----------------------------------------------------
Dans la suite de mon travail, je reprends une vieille requête que j'avais fait en son temps et je dois la modifier toutjours dans le but de réduire le nombre d'enregistrements retournés.

J'ai donc ceci :

Code : Tout sélectionner

$query_ResultJoueurs = sprintf(" SELECT prono_Voteur.NbPointsJoueursL1_Encours, prono_Voteur.Pseudo, prono_Voteur.IdVoteur, prono_Fusion_Voteur_MatchLigue1.IdMatch, prono_Fusion_Voteur_MatchLigue1.NbPointsMarques, prono_Fusion_Voteur_MatchLigue1.BonusCalcule, prono_Fusion_Voteur_MatchLigue1.ScoreEquipeDom, prono_Fusion_Voteur_MatchLigue1.ScoreEquipeVis, prono_Fusion_Voteur_MatchLigue1.Buteur1Dom, prono_Fusion_Voteur_MatchLigue1.Buteur2Dom, prono_Fusion_Voteur_MatchLigue1.Buteur3Dom, prono_Fusion_Voteur_MatchLigue1.Buteur4Dom, prono_Fusion_Voteur_MatchLigue1.Buteur5Dom, prono_Fusion_Voteur_MatchLigue1.Buteur6Dom, prono_Fusion_Voteur_MatchLigue1.Buteur7Dom, prono_Fusion_Voteur_MatchLigue1.Buteur8Dom, prono_Fusion_Voteur_MatchLigue1.Buteur9Dom, prono_Fusion_Voteur_MatchLigue1.Buteur1Vis, prono_Fusion_Voteur_MatchLigue1.Buteur2Vis, prono_Fusion_Voteur_MatchLigue1.Buteur3Vis, prono_Fusion_Voteur_MatchLigue1.Buteur4Vis, prono_Fusion_Voteur_MatchLigue1.Buteur5Vis, prono_Fusion_Voteur_MatchLigue1.Buteur6Vis, prono_Fusion_Voteur_MatchLigue1.Buteur7Vis, prono_Fusion_Voteur_MatchLigue1.Buteur8Vis, prono_Fusion_Voteur_MatchLigue1.Buteur9Vis, prono_Fusion_Voteur_MatchLigue1.HorodatageVote, prono_MatchLigue1.HorodatageMatch FROM prono_Parametres, prono_Voteur INNER JOIN (prono_MatchLigue1 INNER JOIN prono_Fusion_Voteur_MatchLigue1 ON prono_MatchLigue1.IdMatch = prono_Fusion_Voteur_MatchLigue1.IdMatch) ON prono_Voteur.IdVoteur = prono_Fusion_Voteur_MatchLigue1.IdVoteur WHERE (((prono_Fusion_Voteur_MatchLigue1.IdMatch)=%s)) ORDER BY prono_Voteur.NbPointsJoueursL1_Encours DESC , prono_Voteur.Pseudo; ", $colname_ResultJoueurs);
et je souhaite afficher uniquement les résultats pour un IdVoteur = 2 AND un IdVoteur = 3

Je ne sais pas du tout où le positionner au milieu de cette requete comprenant des jointures.

Merci encore !

Jérôme