IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Sélection sur table complexe


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3
    Par défaut Sélection sur table complexe
    Bonjour à tous,
    Je viens vous voir pour vous exposer un problème.
    Je possède la table suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE horaires (
      client_id double unsigned NOT NULL,
      debutPeriode date NOT NULL default '0000-00-00',
      finPeriode date NOT NULL default '0000-00-00',
      jour enum('0','1','2','3','4','5','6') collate utf8_swedish_ci NOT NULL,
      ouverture1 time default NULL,
      fermeture1 time default NULL,
      ouverture2 time default NULL,
      fermeture2 time default NULL,
      note text collate utf8_swedish_ci NOT NULL,
      PRIMARY KEY  (client_id,debutPeriode,finPeriode,jour)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci ROW_FORMAT=COMPACT;
    Cette table contient les horaires d'ouverture de restaurants.
    Les horaires d'ouverture peuvent varier à certaines période de l'année. (Ex: Pendant les 2 mois d'été)

    Je souhaite, lors de la lecture de cette table, lire les horaires qui correspondent à la période actuelle. Je dois donc remplacer les horaires globaux (de période '0000-00-00') par la période concernée.

    Dans l'ordre je fais donc :
    - Select tous les horaires globaux
    - Retire les horaires des jours concernés par une période particulière
    - Ajoute a cette suppression les horaires des jours de la période particulière

    Ce qui correspond au code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * FROM horaires WHERE client_id='2' AND debutPeriode = '0000-00-00' and jour not in ( SELECT  jour FROM horaires as temp WHERE client_id='2' AND ((debutPeriode<=NOW() OR (YEAR(debutPeriode) = '0000' AND MONTH(debutPeriode) <= MONTH(NOW())  AND DAY(debutPeriode) <= DAY(NOW()) ) )    AND     (finPeriode>=NOW() OR (YEAR(finPeriode) = '0000' AND MONTH(finPeriode) >= MONTH(NOW())  AND DAY(finPeriode) >= DAY(NOW()) ) )) ) UNION
     
    ( SELECT  * FROM horaires as temp WHERE client_id='2' AND ((debutPeriode<=NOW() OR (YEAR(debutPeriode) = '0000' AND MONTH(debutPeriode) <= MONTH(NOW())  AND DAY(debutPeriode) <= DAY(NOW()) ) )    AND     (finPeriode>=NOW() OR (YEAR(finPeriode) = '0000' AND MONTH(finPeriode) >= MONTH(NOW())  AND DAY(finPeriode) >= DAY(NOW()) ) )) )
    Cette méthode fonctionne, mais elle répète deux fois la même sélection, et peut être y a-t-il moyen de directement remplacer les n-uplets concerné ?

    Merci beaucoup si quelqu'un peut m'éclairer

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Par défaut
    Bonjour,
    Quel est ce SGBD pour lequel la date du '0000-00-00' existe en tant que date bien sûr.
    De plus j'ai du mal à comprendre tes conditions genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (YEAR(debutPeriode) = '0000' 
    	AND MONTH(debutPeriode) <= MONTH(NOW())  
    	AND DAY(debutPeriode) <= DAY(NOW()) )
    Est-ce à dire que tu as des dates débutPeriodes qui sont dans l'année 0 et qui ont un mois et un jour ordinaire genre 03 février de l'an 0. Quel sens cela a t-il pour toi?
    A+
    Soazig

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3
    Par défaut
    Tout d'habord je te remercie de ta réponse

    Mon SGBD est MySQL.
    En fait j'utilise des dates '0000-00-00' car en tant que primary key, on ne peut pas utiliser de valeur NULL.

    Sinon tu as bien deviné, effectivement, parfois, j'utilise des années avec l'année '0000', cela signifie que la période se répète chaque année, seul le mois importe (c'est la solution qui m'a semblé la plus logique).

    Du coup, dans les deux requete SELECT que j'éxécute, je n'ai trouvé d'autres solution que de la réécrire deux fois, avec un UNION. Je me dis qu'il y a surement une solution bien plus pertinente

    Merci

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Par défaut
    Sur le principe j'ai réécrit ta requête ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    SELECT * FROM horaires 
    WHERE client_id='2' AND debutPeriode = '0000-00-00' 
    AND jour NOT IN (	SELECT  jour 
    					FROM horaires AS temp 
    					WHERE client_id='2' 
    					AND	(	(debutPeriode<=NOW() 
    								OR (YEAR(debutPeriode) = '0000' AND ADDDATE(debutPeriode,INTERVAL year(now()) year) <= NOW())
    							)    AND     
    							(	finPeriode>=NOW() 
    								OR (	YEAR(finPeriode) = '0000' AND ADDDATE(debutPeriode,INTERVAL year(now()) year)  >=NOW()
    									) 
    							)
    				 		)
    				 		) 
    UNION
     
    ( 	SELECT  * FROM horaires AS h2 
    	WHERE client_id='2' 
    	AND	(	(debutPeriode<=NOW() 
    				OR (YEAR(debutPeriode) = '0000' AND ADDDATE(debutPeriode,INTERVAL year(now()) year) <= NOW())
    			)    AND     
    			(	finPeriode>=NOW() 
    				OR (	YEAR(finPeriode) = '0000' AND ADDDATE(debutPeriode,INTERVAL year(now()) year)  >=NOW()
    					) 
    			)
    		)
    )
    Tu peux créer une vue V_MES_PERIODES qui contient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT  * FROM horaires AS h2 
    	WHERE
    	AND	(	(debutPeriode<=NOW() 
    				OR (YEAR(debutPeriode) = '0000' AND ADDDATE(debutPeriode,INTERVAL year(now()) year) <= NOW())
    			)    AND     
    			(	finPeriode>=NOW() 
    				OR (	YEAR(finPeriode) = '0000' AND ADDDATE(debutPeriode,INTERVAL year(now()) year)  >=NOW()
    					) 
    			)
    		)
    Et l'utiliser ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT * FROM horaires 
    WHERE client_id='2' AND debutPeriode = '0000-00-00' 
    AND jour NOT IN (	SELECT  jour 
    					FROM V_MES_PERIODES 
    					WHERE client_id='2' 
     
    				 ) 
    UNION
     
    ( 	SELECT  * FROM V_MES_PERIODES
    )
    Neanmoins ma requête ne doit pas renvoyer exactement la même chose que toi car je considère que si tu es le 31 mai et que ta période est du 01/03/0000 au 03/06/0000 alors le 31 mai est dedans, tandis que pour toi ce sera dehors.

    Ta modélisation est franchement bizarre.
    A+
    Soazig

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3
    Par défaut
    Merci,

    C'est vrai qu'il est possible d'utiliser ADDDATE de la sorte, je n'y ai pas pensé.
    Tu avais oublié de changer debutPeriode, en finPeriode, a deux endroits dans la requete SQL, mais le principe était bon.

    Sinon, la création de la vue était également ce que je recherchais, pour simplifier la création de requetes SQL future sur la base de données.

    Par contre, lorsque tu me dis
    Neanmoins ma requête ne doit pas renvoyer exactement la même chose que toi car je considère que si tu es le 31 mai et que ta période est du 01/03/0000 au 03/06/0000 alors le 31 mai est dedans, tandis que pour toi ce sera dehors.
    Je ne comprends pas tout à fait, après test, ma requête renvoyais bien le même résultat que toi dans une situation similaire.

    Je veux bien admettre que ma modélisation peut paraitre étrange, mais c'est la solution que j'ai trouvé la plus logique.
    L'ajout d'une colonne "repeat" n'aurait pas simplifié la gestion à mon avis.

    Si jamais tu as un conseil concernant la modélisation je suis preneur

    Merci

Discussions similaires

  1. [AC-2007] Requête sélection sur deux tables liées
    Par rogerfon dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 10/04/2010, 14h30
  2. Réponses: 2
    Dernier message: 17/06/2009, 10h12
  3. Sélection sur 2 tables.
    Par morgan47 dans le forum Requêtes
    Réponses: 4
    Dernier message: 12/11/2008, 09h58
  4. Plusieurs jointures sur la meme table [complexe]
    Par Wells dans le forum Requêtes
    Réponses: 2
    Dernier message: 06/06/2006, 11h41
  5. Sélection sur plusieurs tables
    Par WriteLN dans le forum Requêtes
    Réponses: 19
    Dernier message: 05/10/2005, 15h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo