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 :

Requête sql concernant des dates


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut Requête sql concernant des dates
    Bonjour à tous,

    Je viens vers vous car j'ai une requête SQL à faire qui ressemble à un vrai casse-tête chinois et j'aimerai avoir votre avis éclairé.

    Le contexte :
    2 tables
    table 1 : appartement
    table 2 : réservation

    Dans la table réservation j'insère les réservations des appartements avec pour chaque réservation Date de début et date de fin de réservation.

    Jusqu'ici rien de compliqué.

    Mais voilà. Je cherche à lister les disponibilités proches des appartements et là cela devient très compliqué (en tout cas pour moi).

    Pouvez-vous m'aider ?

    Merci à tous,
    Bonne journée.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Salut,
    Pourrais-tu préciser l'environnement sur lequel tu travailles, et détailler la structure de tes tables?
    Merci.

  3. #3
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    peux tu donner un peu plus de renseignement sur tes tables?
    qu'appelles tu disponibilité proche?

    donnes un petit jeu d'essai avec le résultat que tu attends

    Merci

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    Merci pour votre aide.

    Il s'agit d'une base MySql (+ code PHP).

    La base (simplifiée)

    Appartement : AppartId, AppartNom
    Reservation : ResaId, AppartId, DateDebut, DateFin


    Les disponibilités proches sont les appartements n'étant pas réservés dans les prochains jours.

    Exemple :
    Nous sommes le 28 août.
    Il faudrait les appartements disponibles ce jour et les jours suivants (disons dans les 30 prochains jours).
    Par ordre de disponibilité.

    Encore merci pour votre aide.

  5. #5
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    ce n'est pas simplement les appartements donc la date de fin de réservation est avant le 28 août (ou avant le 28 septembre si c'est pour dans 30 jours? )

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    Je pense qu'il faut regarder du côté des fonctions INTERVAL et BETWEEN mais (étonnamment) je n'ai jamais eu à me pencher sur ça.

    Pouvez-vous m'aider à comprendre le principe ?

    Merci à vous 2

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    En fait, ce sont les appartements qui ne sont pas dans la table "reservation" au 28 août et les 30 jours suivant.

    Mais une réservation peut être du 01 août au 30 septembre par exemple.
    Dans ce cas, l'appartement doit être exclus des disponibilités proches.

  8. #8
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    et est ce que une réservation peut commencer le 30 septembre?
    si oui dans ce cas, tu le considère dispo ou pas?

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    Si la réservation commence le 30 septembre mais que l'appartement n'est pas réservé du 28 août au 28 septembre, l'appartement est disponible prochainement.

    Voici un début de requête qui donne les réservations effectives au 28 août

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT AppartId
    FROM reservation
    WHERE (now( ) BETWEEN ResaDebut AND ResaFin)
    Ainsi je peux exclure ces appartements des résultats.

    Mais ce n'est pas suffisant car :
    1/ Cela exclurai les appartement réservés par exemple du 23 au 28 août qui sont pourtant dispo demain.

    Pour simplifier (peut être), il faut l'ensemble des disponibilités prochaines (date non réservées) puis trier par dates libres prochainement.

    J'espère être assez clair.
    Encore merci pour ton aide.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    Il semble qu'il faut utiliser overlaps

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT AppartId FROM reservation
    WHERE ('DateDebut', 'DateFin') overlaps ('2007-03-01', '2007-03-31')
    Mais cela ne fonctionne apparemment pas sous MySql 5 (précision : j'utilise WAMP5).

    Quelqu'un peut-il me confirmer le fonctionnement d'overlaps sous MySql 5 ?

    Merci

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Il semble qu'overlaps ne soit pas encore implémenté, et qu'il ne s'appliquerait pas dans ton cas.
    Ceci dit, je connais très peu mysql, j'ai juste lu un article la dessus.

  12. #12
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    voila une petite lecture : http://sqlpro.developpez.com/cours/gestiontemps/#L1.2.2 sur overlaps

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    Merci.

    Je pense qu'il faut revenir à la base de la réflexion, au niveau de l'algorithme j'ai déjà de grandes difficultés à aborder le problème.

    Considérons que je suis en mesure de retourner l'ensemble des appartements qui ont une réservation comprise entre le 28 août et le 28 septembre.
    (même si la requête que j'ai actuellement pour le faire est franchement pas terrible : utilisation de BETWEEN pour chaque date 1 par 1 avec un OR)

    Ainsi je peux alors ressortir tous les appartements qui ne sont pas réservés pendant cet interval.
    Mais pour certains, même s'ils sont réservés, ils peuvent l'être partiellement.

    Avez-vous une idée des étapes de codes pour répondre au besoin ?

    Encore merci pour votre aide.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    Si j'essais d'imaginer la bonne démarche :

    Exemple :
    une réservation du 28 août au 5 septembre
    une réservation du 12 septembre au 19 septembre

    Cet appartement doit ressortir car libre du 6 au 11 septembre et du 20 au 28 septembre. Dit autrement, pas réservé sur certaines dates comprises entre le 28 août et le 28 septembre.

    Les étapes de l'algo :
    1/ je liste les appartements qui n'ont aucune réservation entre le 28 aout et le 28 septembre
    2/ Pour ceux qui ont des réservations comprises entre le 28 août et le 28 septembre, je liste des intervalles disponibles
    3/ Je regroupe l'ensemble et je liste les intervalles disponibles entre le 28 août et le 28 septembre en triant par date de dispo.

    Ca me semble très lourd, avez-vous une autre idée ?

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    En résumé il faudrait simplement une requête qui permette de ressortir tous les appartements qui ont une date non réservée entre 2 dates.

    Donc une requête du type : est-ce que de telle date à telle date il y a une date qui n'existe pas dans l'intervalle DateDebut, DateFin.


    Snipah, pourquoi cette commande te semble non adaptée dans le contexte ?

    Cybher, merci pour le lien, la requête ne fonctionne pas, erreur de type syntax retournée. As-tu réussi à faire fonctionner ce type de requête sous MySql 5 ?

  16. #16
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    as tu lu la fin de la partie overlaps ou il te donne l'équivalent si overlaps n'existe pas?

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Citation Envoyé par webtheque Voir le message
    Snipah, pourquoi cette commande te semble non adaptée dans le contexte ?
    Parce que j'étais à l'ouest

    Pour ta seconde question, il est noté à la fin du chapitre que t'a indiqué Cybher que si le prédicat overlaps n'est pas dispo, tu peux utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WHERE  (P1_DEBUT > P2_DEBUT AND (P1_DEBUT < P2_FIN OR P1_FIN < P2_FIN)) OR
           (P2_DEBUT > P1_DEBUT AND (P2_DEBUT < P1_FIN OR P2_FIN < P1_FIN)) OR
           (P1_DEBUT = P2_DEBUT AND (P1_FIN IS NOT NULL AND P2_FIN IS NOT NULL))

  18. #18
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Salut,

    En partant du principe que ta table de reservation contient l' historique des reservations sur plusieurs années
    (ce qui paraît crédible, mais il me semblait avoir vu une phrase sous-entendant le contraire).
    Je te propose cette requête (sûrement à adapter, déjà syntaxiquement car je connais mal mysql, par exemple curdate):

    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
     
    /*Ceux qui sont réservés mais prochainement dispos*/
    select a.*
    from appartement a
    where id_app in (select id_app
                         from ( /*En cours de reservation*/
                                select * from reservation where curdate between debut_reserv and fin_reserv
                                EXCEPT
                               /*On retire ceux qui ne sont pas du tout dispos*/
                               select * from reservation
                               where debut_reserv <= curdate and fin_reserv >= curdate+30
                               ) dispo
                      )         
    /*On rajoute ceux qui ne sont pas réservés*/
    union
    select a.*
    from appartement a
    where a.id_app not in (select id_app from reservation where curdate between debut_reserv and fin_reserv)
    Bon je sais pas si c'est suffisant, mais c'est une piste on va dire

    Pour le ORDER BY faut voir avec INTERVAL peut être mais ça va vraiment pas être facile.

    PS : moi overlapps me semble pas adapter parce que t'as que 2 champS date et pas 4, mais j'ai regardé vite fait

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 194
    Points : 93
    Points
    93
    Par défaut
    Bonjour,

    Désolé de ne pas avoir répondu plus tôt.

    Concernant overlaps, la fonction n'est pas disponible sur MySql5.
    J'ai donc utilisé les comparaisons de dates ce qui me permet de ressortir l'ensemble des reservations concernant des appartements qui ont au moins une disponibilité entre les 2 dates.

    En bref, la requête est très lourde, les comparaisons sont faites pour chaque date (de la date du jour à date +30, une par une).
    La requête que tu me propose skuatamad n'est pas correcte car un appartement peut être réservé du 28 aout au 2 septembre puis du 3 septembre au 28 septembre.

    Voici la requête actuelle (vérifie du 28 aout au 08 septembre) :
    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
     
    SELECT a.AppartId, ResaDebut, ResaFin FROM appartement a LEFT JOIN reservation r ON a.AppartId=r.AppartId
    WHERE 
    (
    	'2008-08-28' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-08-29' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-08-30' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-08-31' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-09-01' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-09-02' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-09-03' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-09-04' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-09-05' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-09-06' NOT BETWEEN ResaDebut AND ResaFin
    	OR '2008-09-07' NOT BETWEEN ResaDebut AND ResaFin 
    	OR '2008-09-08' NOT BETWEEN ResaDebut AND ResaFin
    )
     
    OR ResaDebut IS NULL
     
    ORDER BY ResaDebut

    Je cherche maintenant à ressortir uniquement la dernière réservation pour les appartements disponibles.
    Exemple : l'appartement est réservé du 01 juin au 10 juin, puis du 02 aout au 09 aout, il doit me lister uniquement la reservation jusqu'au 09 aout.

    Exemple 2 : l'appartement est aussi réservé du 20 aout au 03 septembre, il doit me lister uniquement la réservation jusqu'au 03 septembre.

    Encore merci pour votre aide.

    Bonne journée

  20. #20
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 810
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 810
    Points : 52 864
    Points
    52 864
    Billets dans le blog
    5
    Par défaut
    Il est beaucoup plus simple de faire un EXISTS entre les plage des dates.
    Quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT...
    FROM ... T1
    WHERE NOT EXISTS(SELECT * 
                     FROM   mesReservations T2 
                     WHERE  JourRéservé BETWEEN JourDebutDemande AND JourFinDemande 
                       AND  T1.MonAppart = T2.monApprt)
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. [AC-2003] Resultat de requête SQL avec des dates incorrect
    Par rockin-bones dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 19/05/2011, 14h35
  2. Réponses: 1
    Dernier message: 03/04/2009, 10h09
  3. [SQL2K] requête SQL, comparer des dates
    Par cortex024 dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 16/03/2006, 14h32
  4. [SQL] selection des dates en ne distinguant pas l'heure
    Par meufeu dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/06/2005, 11h29
  5. [VB.NET] [SQL] Pb requête sql, récupérer des params. ?
    Par Pleymo dans le forum Windows Forms
    Réponses: 3
    Dernier message: 03/02/2005, 20h15

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