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 :

Au moins une date pas comprise dans une fourchette de dates


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juillet 2011
    Messages : 26
    Points : 15
    Points
    15
    Par défaut Au moins une date pas comprise dans une fourchette de dates
    Bonjour,

    je mets en place un projet de recherche travailleurs.
    D'un côté, les travailleurs renseigne leur "non-disponibilite", dans une table SQL avec cette structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CREATE TABLE IF NOT EXISTS `vaca_indisponibilites` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `id_vacataire` int(11) NOT NULL,
      `date_indispo` date NOT NULL,
      `title` varchar(255) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=20 ;
    D'un autre côté, une personne peut faire une recherche de travailleurs disponibles, dans une période donnée, en renseignant une date de début et de fin.

    Je n'arrive pas à construire la requête afin qu'elle retourne les travailleurs qui au moins 1 disponibilité dans la fourchette de date recherchée.
    Vu que la table des travailleurs stockent leur INdisponibilité, il faudrait que la recherche retourne les travailleurs dont au moins une date comprise dans la fourchette de la recherche ne se trouve pas dans leur table d'indisponibilité.

    Toute aide serait bienvenue.
    Merci

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id_vacataire
    FROM vaca_indisponibilites
    WHERE date_indispo NOT BETWEEN $date_debut AND $date_fin

  3. #3
    Membre à l'essai
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juillet 2011
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id_vacataire
    FROM vaca_indisponibilites
    WHERE date_indispo NOT BETWEEN $date_debut AND $date_fin
    La requête fonctionne dans le cas où j'ai bien un enregistrement dans la table des indisponibilités, et que celle-ci n'est pas dans la fourchette de recherche. Par contre, cela ne retourne rien si jamais le travailleur n'a aucune indisponibilité de stockée en base, ce qui est logique.

    Voici la table stockant les travailleurs, qui va devoir intervenir dans la requête j'imagine.

    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
    CREATE TABLE IF NOT EXISTS `vaca_vacataires` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `date_inscription` datetime NOT NULL,
      `date_update` datetime NOT NULL,
      `nom` varchar(255) NOT NULL,
      `prenom` varchar(255) NOT NULL,
      `adresse` varchar(255) NOT NULL,
      `code_postal` varchar(10) NOT NULL,
      `departement` int(11) NOT NULL,
      `region` int(11) NOT NULL,
      `ville` varchar(255) NOT NULL,
      `email` varchar(255) NOT NULL,
      `telephone` varchar(20) NOT NULL,
      `password` varchar(64) NOT NULL,
      `date_naissance` date NOT NULL,
      `lieu_naissance` varchar(255) NOT NULL,
      `secteur` int(11) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;
    J'ai essayé un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT V.id FROM vaca_vacataires V, vaca_indisponibilite D WHERE V.id = D.id_vacataire AND D.date_indispo NOT BETWEEN '2012-08-28' AND '2012-08-30'
    mais cela ne retourne aucun resultat, alors que je n'ai aucune indisponiblité stockée dans ma table.

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Je pense qu'il faut faire un truc dans ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT vaca_vacataires.id
    FROM vaca_vacataires
    LEFT JOIN 
    (
    	SELECT id_vacataire,count(DISTINCT date_indispo ) AS nbJourIndispo
    	FROM vaca_indisponibilites
    	WHERE date_indispo BETWEEN $date_debut AND $date_fin
    	GROUP BY id_vacataire
    ) tmp
    ON vaca_vacataires.id=tmp.id_vacataire AND nbJourIndispo<> datediff($date_fin,$date_debut)
    Tu cherches le nombre de jour d'indisponibilité par vacataire dans la période donnée, puis tu prends tous les vacataires qui ont moins de jour d'indisponibilité qu'il y a de jour dans ta période.

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT v.id
    FROM vaca_vacataires
    WHERE NOT EXISTS
    (
    	SELECT 1
    	FROM vaca_indisponibilites i
    	WHERE i.id_vacataire = v.id
    		AND date_indispo BETWEEN $date_debut AND $date_fin
    )
    Traduction :
    Sélectionner les vacataires pour lesquels il n'existe pas d'indisponibilité entre $date_debut et $date_fin.

    C'est ce que vous voulez non ?

    Nota : BETWEEN inclut les bornes.

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Traduction :
    Sélectionner les vacataires pour lesquels il n'existe pas d'indisponibilité entre $date_debut et $date_fin.
    Personnellement, j'ai compris qu'il voulait sélectionner les vacataires qui ont au moins une disponibilité entre $date_debut et $date_fin

  7. #7
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    les travailleurs renseigne leur "non-disponibilite"
    les travailleurs qui au moins 1 disponibilité dans la fourchette de date recherchée.
    Donc ceux qui n'ont pas déclaré d'indisponibilité dans la période !

  8. #8
    Membre à l'essai
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juillet 2011
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Donc ceux qui n'ont pas déclaré d'indisponibilité dans la période !
    Non justement, la personne est considérée comme disponible si au moins un jour de la fourchette de date ne se trouve pas dans sa table d'indisponibilités. C'est un peu etrange comme fonctionnement, car un employeur preferera a coup sur un vacataire totalement dispo pendant la periode de la mission plutot qu'un vacataire absent un ou plusieurs jours, mais il faut tout de même que la recherche les affiche. Du coup le systeme de fred, basé sur une comparaison de nombre de jours me semble fonctioner.
    Je ne suis plus au boulot là, mais je teste ca dès demain matin et je reviens poster pour confirmer.

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Donc ceux qui n'ont pas déclaré d'indisponibilité dans la période !
    Non, dit autrement "ceux qui n'ont pas déclaré d'indisponibilité pour tous les jours de la période".

    Enfin, on verra bien si Fanel repasse par ici...

    Edit :Il est repassé !

    Edit2 : Ça risque d'être compliqué si il faut gérer les samedi, dimanche etc...

  10. #10
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    En ce cas effectivement, j'avais mal interprété le besoin et la méthode de Fred est la bonne mais comme il dit : quid des jours fériés et week-ends ?

    S'ils doivent être pris en compte, il va falloir modéliser un calendrier.

  11. #11
    Membre à l'essai
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juillet 2011
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Alors, je viens de mettre en place la requête de Fred, qui ne semble pas fonctionner.

    ma table Indisponibilités, avec 2 entrées, pour le vacataire 40.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE IF NOT EXISTS `vaca_indisponibilites` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `id_vacataire` int(11) NOT NULL,
      `date_indispo` date NOT NULL,
      `title` varchar(255) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ;
     
     
    INSERT INTO `vaca_indisponibilites` (`id`, `id_vacataire`, `date_indispo`, `title`) VALUES
    (23, 40, '2012-08-28', ''),
    (22, 40, '2012-08-29', '');
    et ma table vacataires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE TABLE IF NOT EXISTS `vaca_vacataire` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `nom` varchar(255) NOT NULL,
      `prenom` varchar(255) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;
     
    --
    -- Contenu de la table `vaca_vacataire`
    --
     
    INSERT INTO `vaca_vacataire` (`id`,`nom`, `prenom`) VALUES
    (23, 'Nom #1', 'Prenom #1'),
    (40, 'Nom #2', 'Prenom #2');
    La sous-requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT id_vacataire,count(DISTINCT date_indispo ) AS nbJourIndispo
    	FROM vaca_indisponibilites
    	WHERE date_indispo BETWEEN '2012-08-28' AND '2012-08-29'
    	GROUP BY id_vacataire
    me sort bien l'id 40, avec un nbJourIndispo égal à 2, ce qui est correct.

    Par contre la requête complète
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT vaca_vacataires.id
    FROM vaca_vacataires
    LEFT JOIN 
    (
    	SELECT id_vacataire,count(DISTINCT date_indispo ) AS nbJourIndispo
    	FROM vaca_indisponibilites
    	WHERE date_indispo BETWEEN '2012-08-28' AND '2012-08-29'
    	GROUP BY id_vacataire
    ) tmp
    ON vaca_vacataires.id=tmp.id_vacataire AND nbJourIndispo<> datediff('2012-08-29','2012-08-28')
    me sort les ID 23 et 40, alors qu'elle ne devrait me sortir que le 23, puisque le 40 est indisponible le 28 et le 29. J'ai essayé en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND nbJourIndispo<> datediff('2012-08-29','2012-08-28')+1
    , puisque datediff('2012-08-29','2012-08-28') vaut 1, mais cela me retourne également les ID 23 et 40.

    Une idée ?

  12. #12
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Fais plutôt comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT v.id
    FROM vaca_vacataire v
    LEFT JOIN
    (
    	SELECT id_vacataire,
    		count(DISTINCT date_indispo ) AS nbJourIndispo
    	FROM vaca_indisponibilites
    	WHERE date_indispo BETWEEN '2012-08-28' AND '2012-08-29'
    	GROUP BY id_vacataire
    ) tmp
    	ON v.id = tmp.id_vacataire
    WHERE tmp.id_vacataire IS NULL
    	OR tmp.nbJourIndispo < datediff('2012-08-29','2012-08-28') + 1
    Traduction :
    Sélectionne les vacataires non présents dans la table des indisponibilités ou dont le nombre de jours d'indisponibilité est inférieur au nombre de jours de la plage de dates souhaitée.

  13. #13
    Membre à l'essai
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juillet 2011
    Messages : 26
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Fais plutôt comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT v.id
    FROM vaca_vacataire v
    LEFT JOIN
    (
    	SELECT id_vacataire,
    		count(DISTINCT date_indispo ) AS nbJourIndispo
    	FROM vaca_indisponibilites
    	WHERE date_indispo BETWEEN '2012-08-28' AND '2012-08-29'
    	GROUP BY id_vacataire
    ) tmp
    	ON v.id = tmp.id_vacataire
    WHERE tmp.id_vacataire IS NULL
    	OR tmp.nbJourIndispo < datediff('2012-08-29','2012-08-28') + 1
    Traduction :
    Sélectionne les vacataires non présents dans la table des indisponibilités ou dont le nombre de jours d'indisponibilité est inférieur au nombre de jours de la plage de dates souhaitée.
    Celle-ci semble très bien fonctionner par contre. Merci beaucoup.

Discussions similaires

  1. [AC-2010] Comment rechercher si une période est comprise dans une autre ?
    Par [ZiP] dans le forum Requêtes et SQL.
    Réponses: 17
    Dernier message: 09/03/2014, 18h06
  2. Réponses: 1
    Dernier message: 26/12/2010, 21h20
  3. insertion dans une table puis update dans une autre table
    Par uptoditime dans le forum VBA Access
    Réponses: 5
    Dernier message: 10/10/2007, 18h08
  4. Recherche de valeur dans une feuille et affichage dans une autre
    Par Zebulon777 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 15/05/2007, 09h40
  5. Réponses: 3
    Dernier message: 06/09/2006, 09h06

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