Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 13/05/2011, 22h18   #1
Invité de passage
 
David
Inscription : avril 2010
Messages : 8
Détails du profil
Informations personnelles :
Nom : David

Informations forums :
Inscription : avril 2010
Messages : 8
Points : 2
Points : 2
Par défaut [Doctrine] Conditions sur tous les résultats de la requête

Bonsoir tout le monde,

J'ai un problème avec une de mes requettes Doctrine.

J'ai deux tables sql (géré via phpmyadmin) avec l'architecture suivante.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$this->setTableName('salle');
 
		//Puis, tous les champs
        $this->hasColumn('id_salle', 'integer', 50, array('primary' => true,
						   'autoincrement' => true));
		$this->hasColumn('nb_reservation','integer',50, array('default' => 0));
		$this->hasColumn('nb_places','integer',50);
        $this->hasColumn('nom_salle', 'string', 100);
		$this->hasColumn('type_salle', 'string', 100);
		$this->hasColumn('commentaire', 'string', 4000);
		$this->hasColumn('acces_handicape','string',10);
    }
 
	    public FUNCTION setUp()
    {
        $this->hasMany('BaseReservation as BaseReservation', array('local' => 'id_salle', 'foreign' => 'id_salle'));
    }
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
// ON définit le nom de notre TABLE : « salle ».
        $this->setTableName('reservation');
 
		//Puis, tous les champs
        $this->hasColumn('id_reservation', 'integer', 50, array('primary' => true,
						   'autoincrement' => true));
		$this->hasColumn('id_salle','integer',50);
		$this->hasColumn('nom','string',25);
        $this->hasColumn('date_debut', 'integer', 50);
		$this->hasColumn('date_fin', 'integer', 50);
    }
J'ai créé la requette suivante :
Code :
1
2
3
4
5
6
 
$requete_salle_dispo_date = Doctrine_Query::CREATE()
			->SELECT('id_salle,nom_salle')
			->FROM('BaseSalle s')
			->leftJoin('s.BaseReservation r')
			->WHERE('(s.nb_reservation = 0 AND type_salle = "'.$type_salle.'" AND nb_places >= '.$nb_place.') OR s.id_salle = r.id_salle AND r.date_debut NOT BETWEEN '.$date_debut.' AND '.$date_fin.' AND r.date_fin NOT BETWEEN '.$date_debut.' AND '.$date_fin.' AND type_salle = "'.$type_salle.'" AND nb_places >= '.$nb_place);
Je veux récupérer l'id et le nom des salles qui ne sont pas reservé à une date donné, avec d'autre conditions comme le type de salle et le nombre de places disponibles.
Mon problème ici est que ma requette effectue bien le test sur date_debut et date_fin du premier champ trouvé sur la table reservation mais ne va pas plus loin. Il peut y avoir plusieurs reervation pour une même salle à différentes dates, mais le test ne s'effectue que sur le premier resultat trouvé.

Comment faire en sorte que ma requette fasse un test sur TOUS les champs de ma table reservation respectant s.id_salle = r.id_salle ?
Faut t'il faire intervenir une boucle ?.

Je ne suis pas sur d'etre clair , n'hésitez pas si vous avez des questions, je vous remercie.

David.
Didiplouf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2011, 00h37   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 001
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 001
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
Écris la requête en SQL pur, ce sera plus lisible et plus facile à débugguer.

Si tu as des conditions dans le WHERE qui concernent la table de droite de la jointure externe gauche, cela revient à faire une jointure interne. Voir explication sur mon blog.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2011, 12h03   #3
Invité de passage
 
David
Inscription : avril 2010
Messages : 8
Détails du profil
Informations personnelles :
Nom : David

Informations forums :
Inscription : avril 2010
Messages : 8
Points : 2
Points : 2
Bonjour, je te remercie de ta réponse

En simplifiant le problème au salle disponible à une date donnée j'obtient ceci en requete sql pur.

Code :
1
2
3
4
5
SELECT r.id_salle, s.nom_salle
FROM reservation r, salle S
WHERE r.id_salle = s.id_salle
  AND r.date_debut NOT BETWEEN '.$date_debut.' AND '.$date_fin.' 
  AND r.date_fin NOT BETWEEN '.$date_debut.' AND '.$date_fin.';
EN y reflechissant un peut plus je penses que mon problème est autre part, et que je devrais tourner ma requette d'une autre façon. Car la je demande bien de me renvoyer tous les id et nom salle qui sont disponibles.
Hors si il y a plusieurs fois la même salle reservé par exemple:

Le lundi de 8h à 10h la salle 1 est reservé.
Le mardi de 8h à 10h la salle 1 est reservé.

Si je demande les salles dispos le lundi de 8h à 10h il me renverra la salle 1 car elle apparaît une deuxième fois dans la table réservation à une date différente...

Avez vous une idée de comment je pourrais modifier tout ca pour obtenir ce que je veux ?
Didiplouf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/05/2011, 16h06   #4
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 001
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 001
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
Une réservation est définie par une date de début de réservation DRR et de fin de réservation DFR.

Pour savoir si une salle est libre entre une date D1 et une date D2, il faut qu'il n'existe pas de réservation pour cette salle satisfaisant les conditions suivantes :
- D1 entre DRR et DFR
ou D2 entre DRR et DFR
ou (D1 < DRR et D2 > DFR)

Vu que tu utilises MySQL qui ne connait pas la fonction OVERLAPS, voici la traduction en SQL pour MySQL :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT s.id_salle, s.nom_salle
FROM salle s
WHERE NOT EXISTS
(
	SELECT *
	FROM reservation r
	WHERE r.id_salle = s.id_salle
		AND
		(
			'$date_debut' BETWEEN r.date_debut AND r.date_fin
			OR '$date_fin' BETWEEN r.date_debut AND r.date_fin
			OR
			(
				'$date_debut' < r.date_debut
				AND '$date_fin' > r.date_fin
			)
		)
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 14/05/2011, 16h15   #5
Invité de passage
 
David
Inscription : avril 2010
Messages : 8
Détails du profil
Informations personnelles :
Nom : David

Informations forums :
Inscription : avril 2010
Messages : 8
Points : 2
Points : 2
Merci de ta réponse cinephil,

Effectivement ça a l'air beaucoup plus simple comme ça , je n'avais pas tourné ce problème dans ce sens.

J'avais pensé à sélectionner toutes les salles qui ont une réservation aux dates données, et ensuite faire un select de toutes les salles sauf celles sélectionnées précédemment !.

Mais ta solution est beaucoup plus propre et simple, je teste ça dans la journée et je te tiens au courant.

Merci encore,

David.D

Edition : J'ai tout retranscrit sur Doctrine, effectué plusieurs tests et tout fonctionne parfaitement, je te remercie beaucoup cinephil à bientôt .
Didiplouf est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h24.


 
 
 
 
Partenaires

Hébergement Web