Requete avec subquery

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 : Requete avec subquery

par agité » 05 nov. 2007, 15:45

la requete se fait bien mais les reponses se font pour chaque ID commune.
Logique puisque
JOIN programme ON (programme.Id = lot.Id_programme)
Au fond on ne sait pas ce que tu veux obentir :?
Oui j'avais oublier de mettre les groupes :
SELECT * FROM `lot` 
INNER JOIN programme ON (programme.Id = lot.Id_programme)
WHERE Id_region LIKE '".$Option2."' 
AND Id_fiscalite LIKE '".$Option1."'
AND Id_genre LIKE '".$Option3."'
AND Prix_base BETWEEN '".$Prix_min."' 
AND '".$Prix_max."' GROUP BY Id_programme
Maintenant tout marche :)

par Truc » 05 nov. 2007, 15:28

la requete se fait bien mais les reponses se font pour chaque ID commune.
Logique puisque
JOIN programme ON (programme.Id = lot.Id_programme)
Au fond on ne sait pas ce que tu veux obentir :?

par agité » 05 nov. 2007, 14:44

J'ai essayer ave des distinct :
("
SELECT DISTINCT * FROM `lot` 
INNER JOIN (SELECT DISTINCT * FROM programme WHERE programme.Id = lot.Id_programme) 
WHERE Id_region LIKE '".$Option2."' 
AND Id_fiscalite LIKE '".$Option1."' 
AND Id_genre LIKE '".$Option3."' 
AND Prix_base BETWEEN '".$Prix_min."' 
AND '".$Prix_max."' 
")
mais il ne semble pas les prendre en compte

par agité » 05 nov. 2007, 13:48

C'est bien, on avance presque. Maintenant il ne te reste plus qu'à poster ta requête telle qu'elle est exécutée, plutôt que tout ce PHP qui ne nous sert à rien.
Elle depend des parametres envoyées par la recherche et donc n'est pas éxecutée de la même maniere a chaque fois.

SINON :
SELECT * FROM `lot`
INNER JOIN programme ON (programme.Id = lot.Id_programme)
WHERE Id_region LIKE 'O'
AND Id_fiscalite LIKE 'ROB'
AND Id_genre LIKE 'APPA'
AND Prix_base BETWEEN '0' AND '200'

par Hubert Roksor » 05 nov. 2007, 13:44

C'est bien, on avance presque. Maintenant il ne te reste plus qu'à poster ta requête telle qu'elle est exécutée, plutôt que tout ce PHP qui ne nous sert à rien.

par agité » 05 nov. 2007, 13:24

Quand je fais cette requete en fait il ya toujours un probleme, cette fois ci, la requete se fait bien mais les reponses se font pour chaque ID commune.

les tables concernées :

Code : Tout sélectionner

CREATE TABLE `programme` ( `Id` int(11) NOT NULL auto_increment, `Nom` varchar(255) collate utf8_unicode_ci NOT NULL, `Adresse` varchar(255) collate utf8_unicode_ci default NULL, `Cp` varchar(5) collate utf8_unicode_ci NOT NULL, `Ville` varchar(70) collate utf8_unicode_ci NOT NULL, `Id_region` varchar(5) collate utf8_unicode_ci NOT NULL, `Date_comm` varchar(255) collate utf8_unicode_ci default NULL, `Date_livraison` varchar(255) collate utf8_unicode_ci default NULL, `Date_signature` varchar(255) collate utf8_unicode_ci default NULL, `Id_fiscalite` varchar(5) collate utf8_unicode_ci NOT NULL, `Presentation` text collate utf8_unicode_ci, `Photo_0` varchar(255) collate utf8_unicode_ci default NULL, `Photo_1` varchar(255) collate utf8_unicode_ci default NULL, `Photo_2` varchar(255) collate utf8_unicode_ci default NULL, UNIQUE KEY `Id` (`Id`), KEY `id_region` (`Id_region`), KEY `id_fiscalite` (`Id_fiscalite`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;
et

Code : Tout sélectionner

CREATE TABLE `lot` ( `Id` int(11) NOT NULL auto_increment, `Id_programme` int(11) NOT NULL, `Code` varchar(10) collate utf8_unicode_ci NOT NULL, `Etage` int(2) default NULL, `Rentabilite` float default NULL, `Id_genre` varchar(5) collate utf8_unicode_ci NOT NULL, `Id_orientation` varchar(5) collate utf8_unicode_ci NOT NULL, `Id_type` varchar(5) collate utf8_unicode_ci NOT NULL, `Surface_total` float default NULL, `Surface_hab` float default NULL, `Prix_base` float default NULL, `Prix_pack2` float default NULL, `Loyer_mensuel` float default NULL, `Loyer_borloo` float default NULL, `Loyer_robien` float default NULL, `Infos_supp` text collate utf8_unicode_ci NOT NULL, `Id_etat` enum('signature','uncom','option','fax','reserv','disponible') collate utf8_unicode_ci NOT NULL default 'disponible', `Date_chgmt_etat` datetime default NULL, `Livraison` varchar(255) collate utf8_unicode_ci default NULL, `Id_vendeur` int(11) NOT NULL, `Nom_vendeur` varchar(255) collate utf8_unicode_ci default NULL, `Acheteur` varchar(255) collate utf8_unicode_ci default NULL, PRIMARY KEY (`Id`), KEY `id_programme` (`Id_programme`), KEY `id_genre` (`Id_genre`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;
La fonction :


function Lister_Lots($Option1,$Option2,$Option3,$Prix_min,$Prix_max)
{

$Req_Liste_Lot = mysql_query("
SELECT * FROM `lot` 
INNER JOIN programme ON (programme.Id = lot.Id_programme) 
WHERE Id_region LIKE '".$Option2."' 
AND Id_fiscalite LIKE '".$Option1."' 
AND Id_genre LIKE '".$Option3."' 
AND Prix_base BETWEEN '".$Prix_min."' 
AND '".$Prix_max."' ") or die(mysql_error());

	while($Array_Liste_Lot = mysql_fetch_array($Req_Liste_Lot))
	{
?>
			<tr>
			<td><?php echo $Array_Liste_Lot['Cp']; ?></td>
			<td><?php echo $Array_Liste_Lot['Ville']; ?></td>
			<td><?php echo $Array_Liste_Lot['Id']; ?></td>
			<td><?php echo $Array_Liste_Lot['Id_type']; ?></td>
			<td><?php echo $Array_Liste_Lot['Id_genre']; ?></td>
			<td><?php echo $Array_Liste_Lot['Etage']; ?></td>
			<td><?php echo $Array_Liste_Lot['Id_etat']; ?></td>  	
			<td><?php echo $Array_Liste_Lot['Prix_base']; ?></td> 
			<td><?php echo $Array_Liste_Lot['Loyer_mensuel']; ?></td>
			</tr>
			
<?php	
	}
}

par agité » 05 nov. 2007, 13:02

  • poste le schéma des tables pertinentes à ta requête sous la forme d'une instruction "CREATE TABLE"
  • poste tes requêtes telles qu'elles sont exécutées. Tout ce PHP nuit à la lecture. Ne mets pas toute ta requête sur une seule ligne si tu veux que les gens la lise et/ou comprenne
  • c'est normal que tu aies des résultats, tu joins 2 tables sans condition de jointure donc le serveur en fait le produit cartésien
Desole pour ne pas avoir tout mis d'un seul coup, finalement j'ai réussi a comprendre grace ton idée sur les jonctions de table, en effet si je ne foins rien c'est un peu n'importe quoi comme requete.

La reponse est :
SELECT * FROM `lot`
INNER JOIN programme ON (programme.Id = lot.Id_programme) 
WHERE Id_region LIKE '".$Option2."' AND Id_fiscalite LIKE '".$Option1."' AND Id_genre LIKE '".$Option3."' AND Prix_base BETWEEN '".$Prix_min."' AND '".$Prix_max."';

par Hubert Roksor » 05 nov. 2007, 12:51

  • poste le schéma des tables pertinentes à ta requête sous la forme d'une instruction "CREATE TABLE"
  • poste tes requêtes telles qu'elles sont exécutées. Tout ce PHP nuit à la lecture. Ne mets pas toute ta requête sur une seule ligne si tu veux que les gens la lise et/ou comprenne
  • c'est normal que tu aies des résultats, tu joins 2 tables sans condition de jointure donc le serveur en fait le produit cartésien

par agité » 05 nov. 2007, 12:43

Quand je fais ce type de requete :
$Req_Liste_Lot = mysql_query("SELECT * FROM `lot`,`programme` WHERE Id_genre LIKE '".$Option3."' AND Prix_base BETWEEN '".$Prix_min."' AND '".$Prix_max."' AND Id_region LIKE '".$Option2."' AND Id_fiscalite LIKE '".$Option1."' ") or die(mysql_error());
	
	while($Array_Liste_Lot = mysql_fetch_array($Req_Liste_Lot))
	{ blablablabla }
Il me retourne 3 fois chaque entrée du tableau, quand je retire la requete sur programme et que je vire les 2 AND de la fin ca me retourne bien qu'un enregistrement a chaque fois.

Je ne comprends pas pourquoi il me retourne 3 fois chaque entrée, une idée ?

par agité » 05 nov. 2007, 12:31

Merci Ryle mais quand je fais plusieurs recherche sur une table je veux laisser des conditions vides, comme par exemple SELCT * FROM machin WHERE truc = % AND bidule = 1000 .

En fait c'est pour un moteur de recherche, donc toute les conditions ne sont pas forcement envoyées.

par Ryle » 05 nov. 2007, 12:25

Il n'y a pas de jonctions entre les tables
Doit quand même bien y avoir un lien entre la table "programme" de ta requête principale et la table "programme" de ta sous requête nan ? Pourquoi faire simple... ;)
Au lieu de :

Code : Tout sélectionner

WHERE (Id_region,Id_fiscalite) IN ( SELECT Id_region,Id_fiscalite FROM programme WHERE Id_Region LIKE '".$Option2."' AND Id_fiscalite LIKE '".$Option1."' )
Pourquoi ne pas simlpement faire

Code : Tout sélectionner

WHERE Id_Region LIKE '".$Option2."' AND Id_fiscalite LIKE '".$Option1."'
:?:
j'utilise le LIKE puisque ma requete contient comme valeur par defaut le joker sql %, ce qui permet de faire une recherche avec LIKE '%'.
C'est pas mieux pour autant. Au lieu d'ajouter une condition qui filtre ta requête en autorisant tout, ce qui aura pour effet de scanner toute ta table pour s'assurer que tous tes enregistrements correspondent bien à la valeur recherchée, suffit juste de ne pas mettre la condition :)

Re: Requete avec subquery

par agité » 05 nov. 2007, 12:22

comme la requetes est en sql mais qu'elle est appelé depuis php je la met dans cette rubrique
Oui et comme ma voiture consome de l'essence je me dis que c'est bien de l'amener chez le pompiste pour apprendre à la conduire.

:arrow: Je déplace
:oops:

sinon en fait c'était beaucoup plus simple de faire comme ca :
$Req_sql = mysql_query("SELECT * FROM lot,programme WHERE Id_region LIKE '".$Option2."' AND Id_fiscalite LIKE '".$Option1."' AND Id_genre LIKE '".$Option3."' AND Prix_base BETWEEN '".$Prix_min."' AND '".$Prix_max."' ") or die(mysql_error());
:roll:

Re: Requete avec subquery

par Truc » 05 nov. 2007, 12:09

comme la requetes est en sql mais qu'elle est appelé depuis php je la met dans cette rubrique
Oui et comme ma voiture consome de l'essence je me dis que c'est bien de l'amener chez le pompiste pour apprendre à la conduire.

:arrow: Je déplace

par agité » 05 nov. 2007, 12:01

Rien de plus à ajouter aux explications de d0m, juste une petite remarque sur le fait qu'une jointure entre tes tables serait bien plus appropriée qu'une sous requête

Code : Tout sélectionner

SELECT ... FROM table1, table2 WHERE table1.champX = table2.champY AND table1.champZ = ... ...
Par ailleurs, si tu fais une comparaison identique de valeur, utilises l'opérateur "=" au lieu de "LIKE", ne mets pas d'apostrophes autour de valeurs numériques, et liste les champs que tu souhaites récupérer au lieu de faire un SELECT * (cf. la FAQ pour en savoir un peu plus sur les bonnes pratiques SQL ;))
Il n'y a pas de jonctions entre les tables, j'utilise le LIKE puisque ma requete contient comme valeur par defaut le joker sql %, ce qui permet de faire une recherche avec LIKE '%'.

par Ryle » 05 nov. 2007, 11:38

Rien de plus à ajouter aux explications de d0m, juste une petite remarque sur le fait qu'une jointure entre tes tables serait bien plus appropriée qu'une sous requête

Code : Tout sélectionner

SELECT ... FROM table1, table2 WHERE table1.champX = table2.champY AND table1.champZ = ... ...
Par ailleurs, si tu fais une comparaison identique de valeur, utilises l'opérateur "=" au lieu de "LIKE", ne mets pas d'apostrophes autour de valeurs numériques, et liste les champs que tu souhaites récupérer au lieu de faire un SELECT * (cf. la FAQ pour en savoir un peu plus sur les bonnes pratiques SQL ;))