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 :

Opérations avec Jours Fériés


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 15
    Points
    15
    Par défaut Opérations avec Jours Fériés
    Bonjour,

    Je suis en train de me casser la tête sur les jours fériés :

    J'ai deux tables :
    - la première comporte deux dates : une date de début et une date de fin (2 datetime)
    - la deuxième, une liste de jours fériés hors Weekend (datetime)

    je voudrais afficher la première table modifiée de la manière suivante : la date de fin + 1 j si il existe dans la deuxième table une date comprise entre la date de début et la date de fin, sinon on affiche la date de fin modifiée.

    Merci de votre aide.

    Cdt,

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Tu ne veux pas plutôt reporter la date de fin du nombre de jours qui chevauchent la période demandée avec les jours fériés ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 15
    Points
    15
    Par défaut
    Bien sur !

    L'ajout d'un jour n'est en effet pas exaxte car il peut y avoir plusieurs jours fériés sur la même période.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 15
    Points
    15
    Par défaut Redéfinition du problème
    Dans une table A j'ai une liste de dates :
    - une date de début DATE_DEB (DATETIME)
    - une date de fin DATE_FIN (DATETIME)

    Dans une table B j'ai la liste des jours fériés de l'année :
    - une date de jour férié hors weekend JOURFERIE (DATETIME)

    Je voudrais faire un UPDATE de DATE_FIN par DATE_FIN + N jours (dans la table A) lorsque sur la période ]DATE_DEB;DATE_FIN] il existe N jours fériés et bien sûr ne pas mettre à jour s'il n'y a pas de jour férié sur la période.

    Est-ce plus clair ?

    PS : Il s'agit uniquement de DATETIME à 00:00:00 (pas de travail sur l'heure)

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Essaie ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select Table_a.date_deb, Table_a.date_fin, Count(table_b.jourferie)
    From Table_a, Table_b
    Where Exists (	Select * 
    		From Table_b 
    		Where Table_b.jourferie 	
    		Between Table_a.date_deb And Table_a.date_deb)
    Group By Table_a.date_deb, Table_a.date_fin
    Je n'ai pas testé, c'est un premier jet qui donne matière à réflexion. la requête est censée donner pour chaque plage [date_deb, dete_fin] de Table A le nombre de jour férié qu'elle comprend. Si elle passe, tu n'as plus qu'à additionner ça avec ta date de fin et tu auras la plage modifiée.

    edit : cette requête ne retournerait pas les enregistrements de table_a qui n'ont pas de jours fériés dans la plage. Pas fameux fameux...

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 15
    Points
    15
    Par défaut
    Résultat de la proposition :

    DATE_DEB|DATE_FIN|COUNT
    2007-05-01 00:00:00.000|2007-05-08 00:00:00.000|765
    2007-05-08 00:00:00.000|2007-05-15 00:00:00.000|729
    2007-05-17 00:00:00.000|2007-05-24 00:00:00.000|630
    2007-05-28 00:00:00.000|2007-06-04 00:00:00.000|810

    Moi, je pensais plutot faire un curseur sur chaque jour férié et, SI le jour férié courant (curseur) apartient à la plage ]DATE_DEB;DATE_FIN] faire un UPDATE de DATE_FIN avec DATE_FIN + 1, SINON ne rien faire.

    Qu'en pensez vous ?

    PS : J'ai filtrer depuis mai-07

  7. #7
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Désolé pour ma proposition précédante. J'ai mélangé les deux solutions que je voulais t'écrire. Du coup le nombre de lignes retournées pour table_b est complètement erroné.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Table_a.date_deb, Table_a.date_fin, Count(table_b.jourferie)
    FROM Table_a, Table_b
    WHERE table_b.jourferiere BETWEEN table_a.date_deb AND table_a.date_fin
    GROUP BY Table_a.date_deb, Table_a.date_fin
    Essaie ça plutôt

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 782
    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 782
    Points : 52 780
    Points
    52 780
    Billets dans le blog
    5
    Par défaut
    d'après mon papier sur la gestion du temps dans les bases de données :
    http://sqlpro.developpez.com/cours/gestiontemps/

    Avec une table de toutes les dates et une colone spécifiant les jours fériés :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    CREATE TABLE T_PERIODE_PRD 
    (PRD_ID    INT NOT NULL PRIMARY KEY, 
     PRD_DEBUT DATETIME NOT NULL, 
     PRD_FIN   DATETIME NOT NULL,
     CONSTRAINT CK_PRD_COHERENCE CHECK (PRD_FIN > PRD_DEBUT))
    GO
     
    CREATE TABLE T_JOUR_JOR
    (JOR_DATE  DATETIME NOT NULL PRIMARY KEY,
     JOR_FERIE BIT NOT NULL DEFAULT 0)
    GO
     
    -- jeu d'essais :
     
    INSERT INTO T_PERIODE_PRD VALUES (1, '20071218', '20071225')
    INSERT INTO T_PERIODE_PRD VALUES (2, '20071219', '20080101')
    INSERT INTO T_PERIODE_PRD VALUES (3, '20071220', '20080105')
     
    DECLARE @J DATETIME
    SET @J = '20071201'
     
    WHILE @J < '20080131'
    BEGIN
       INSERT INTO T_JOUR_JOR (JOR_DATE) VALUES (@J)
       SET @J = @J + 1
    END
    GO
     
    UPDATE T_JOUR_JOR
    SET JOR_FERIE = 1
    WHERE JOR_DATE IN ('20071225', '20080101')
    GO
     
     
    -- requête :
     
    SELECT PRD_ID, PRD_DEBUT, PRD_FIN, 
           MIN(JOR_DATE) AS PRD_FIN_FERIE, 
           DATEDIFF(d,PRD_DEBUT,  MIN(JOR_DATE)) AS PRD_DUREE_JOUR
    FROM   T_PERIODE_PRD
           INNER JOIN T_JOUR_JOR
                 ON PRD_FIN <= JOR_DATE
    WHERE  JOR_FERIE = 0
    GROUP  BY PRD_ID, PRD_DEBUT, PRD_FIN
     
    PRD_ID      PRD_DEBUT   PRD_FIN     PRD_FIN_FERIE PRD_DUREE_JOUR 
    ----------- ----------- ----------- ------------- -------------- 
    1           2007-12-18  2007-12-25  2007-12-26    8
    2           2007-12-19  2008-01-01  2008-01-02    14
    3           2007-12-20  2008-01-05  2008-01-05    16
     
     
    -- raffinement : si vous voulez en sus gérer les jours ouvrables, modifiez comme suit :
     
     
    ALTER TABLE T_JOUR_JOR
    ADD JOR_OUVRABLE INT NOT NULL DEFAULT 1
    GO
     
    UPDATE T_JOUR_JOR
    SET    JOR_OUVRABLE = 0
    WHERE  DATEPART(dw, JOR_DATE) IN (6 ,7)
    GO
     
    -- requête :
     
    SELECT PRD_ID, PRD_DEBUT, PRD_FIN, 
           MIN(JOR_DATE) AS PRD_FIN_FERIE, 
           (SELECT SUM(JOR_OUVRABLE) 
            FROM   T_JOUR_JOR 
            WHERE  JOR_DATE BETWEEN PRD.PRD_DEBUT 
                                AND MIN(JOR.JOR_DATE)) AS PRD_DUREE_JOUR_OUVRES
    FROM   T_PERIODE_PRD AS PRD
           INNER JOIN T_JOUR_JOR AS JOR
                 ON PRD_FIN <= JOR_DATE
    WHERE  JOR_FERIE = 0 
    AND    JOR_OUVRABLE = 1
    GROUP  BY PRD_ID, PRD_DEBUT, PRD_FIN
     
    PRD_ID      PRD_DEBUT   PRD_FIN     PRD_FIN_FERIE PRD_DUREE_JOUR_OUVRES 
    ----------- ----------- ----------- ------------- ---------------------
    1           2007-12-18  2007-12-25  2007-12-26    7
    2           2007-12-19  2008-01-01  2008-01-02    11
    3           2007-12-20  2008-01-05  2008-01-07    13
    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/ * * * * *

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 15
    Points
    15
    Par défaut Trouvé !
    Merci pour ta réponse.

    J'ai continué à chercher en parallèle et j'ai finalement trouvé une solution avec un curseur JOURFERIE :

    Voilà le bout de code :
    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
    --Vérification de l'existence d'un jour férié dans la période
    DECLARE @ferie DATETIME
    DECLARE curseur_jf CURSOR FOR
    SELECT jourferie FROM Suivi..joursferie
    OPEN curseur_jf
    FETCH curseur_jf INTO @ferie
    WHILE @@FETCH_STATUS = 0
    	BEGIN
    		--MàJ de la date de promesse d'appro en fonction du jour de la semaine
    		UPDATE #TMP_promesse
    		SET DATE_FIN = FIN + 1
    		WHERE DATE_DEB < @ferie AND DATE_FIN >= @ferie
    		UPDATE #TMP_promesse
    		SET DATE_FIN = DATE_FIN + 1
    		WHERE DATEPART(dw, DATE_FIN) = 6 OR DATEPART(dw, DATE_FIN) = 7
    		UPDATE #TMP_promesse
    		SET DATE_FIN = DATE_FIN + 1
    		WHERE DATEPART(dw, DATE_FIN) = 7
    	FETCH curseur_jf INTO @ferie
    	END
    CLOSE curseur_jf
    DEALLOCATE curseur_jf
    Pour chaque jour férié que je rencontre, je parcours l'intégralité de mes périodes.

    SI je tombe sur une période comportant un jour férié, je met à jour ma date de fin avec +1j,
    SI cette date deviens un samedi ou un dimanche, je fais encore +1j, enfin,
    SI cette date deviens un dimanche je fais encore +1j

    Il y avait plus optimal mais bon... sa marche pas trop mal.
    Merci beaucoup pour votre aide

    Bye,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Calcul de jours ouvrés avec jours fériés entre deux dates
    Par grimgrim dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 13/03/2015, 21h12
  2. [11g] Calendrier avec jours fériés
    Par Waldar dans le forum Contribuez
    Réponses: 3
    Dernier message: 20/06/2014, 14h04
  3. Calendrier avec jours fériés
    Par lolo6413 dans le forum Requêtes
    Réponses: 1
    Dernier message: 27/09/2013, 14h58
  4. Réponses: 3
    Dernier message: 13/10/2011, 13h28
  5. [Dates] Gestion d'un calendrier avec les jours fériés
    Par maximenet dans le forum Langage
    Réponses: 4
    Dernier message: 05/05/2006, 08h41

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