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

SQL Oracle Discussion :

Calculer une période de congés


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 18
    Par défaut Calculer une période de congés
    Bonjour,

    Je dois calculer une période de date de congés sur un mois donnée, par membre du personnel.
    J'ai une table Oracle contenant l'Id d'une personne, la date, le numéro de la semaine et un flag qui indique si la personne à posé un jour de congés ou non.
    Il y a une date par ligne et par personne.

    Exemple :
    ID Personne	Date	Num Semaine	Congés
    1234	01/03/2013	9	             OUI
    1234	02/03/2013	9	             OUI
    1234	03/03/2013	9	             OUI
    1234	04/03/2013	10	             OUI
    1234	05/03/2013	10	             NON
    1234	06/03/2013	10	             NON
    1234	07/03/2013	10	             NON
    1234	08/03/2013	10	             OUI
    1234	09/03/2013	10	             OUI
    Dans ce cas là, les périodes de congés qui je souhaite trouver sont : du 01/03/2013 au 04/03/2013 et du 08/03/2013 au 09/03/2013.

    Est ce que quelqu'un serait comment déterminer ces périodes ?

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    bonjour,


    avec les fonctions de fenêtrage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    with tmp as (
    select id_personne, dte, conges, row_number() over(partition by id_personne order by dte) - row_number() over(partition by id_personne, conges order by dte) as rnk
    from ma_table)
     
    select id_personne, min(dte) as dte_deb, max(dte) as dte_max
    from tmp
    where conges = 'OUI'
    group by id_personne, rnk

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 134
    Par défaut
    Pour traiter ce problème il suffit de le décomposer :
    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
    WITH    debut   --  La date de début de période de congés
    AS  (   SELECT  tb1.id_personne
                ,   tb1."date"      AS debut
            FROM    matable tb1
            WHERE   tb1.conges  = 'OUI'
                AND NOT EXISTS  -- début si jour = congés et veille != congés
                    (   SELECT  NULL
                        FROM    matable tb2
                        WHERE   tb2.conges  = 'OUI'
                            AND tb2.id_personne = tb1.id_personne
                            AND tb2."date"      = tb1."date" -1
                    ) 
        )
        ,   fin   --  La date de fin de période de congés
    AS  (   SELECT  tb1.id_personne
                ,   tb1."date"      AS fin
            FROM    matable tb1
            WHERE   tb1.conges  = 'OUI'
                AND NOT EXISTS  -- fin si jour = congés et lendemain != congés
                    (   SELECT  NULL
                        FROM    matable tb2
                        WHERE   tb2.conges  = 'OUI'
                            AND tb2.id_personne = tb1.id_personne
                            AND tb2."date"      = tb1."date" + 1
                    ) 
        )
        ,   per_debut   -- Numéroter les périodes de congés
    AS  (   SELECT  tb1.id_personne
                ,   tb1.debut
                ,   ROW_NUMBER() OVER (PARTITION BY tb1.id_personne ORDER BY tb1.debut)  AS periode
            FROM    debut   tb1
        )
        ,   per_fin
    AS  (   SELECT  tb1.id_personne
                ,   tb1.fin
                ,   ROW_NUMBER() OVER (PARTITION BY tb1.id_personne ORDER BY tb1.fin)  AS periode
            FROM    debut   tb1
        )
    SELECT  tb1.id_personne
        ,   tb1.periode
        ,   tb1.debut
        ,   tb2.fin
    FROM    per_debut   tb1
        INNER JOIN
            per_fin     tb2
            ON  tb2.id_personne = tb1.id_personne
            AND tb2.periode     = tb1.periode       -- Regrouper les périodes
    ;
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  4. #4
    Membre averti
    Femme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 18
    Par défaut Merci
    Merci beaucoup pour ces réponses

    Je vais tester ça et vous tiens au courant

  5. #5
    Membre averti
    Femme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 18
    Par défaut
    J'ai une autre question.
    Si je veux ajouter un regroupement par type de congés, ça donnerai quoi comme requête ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     Exemple:
    ID Personne	Date	Num Semaine	Congés	Type
    1234	01/03/2013	9	             OUI	CP
    1234	02/03/2013	9	             OUI	CP
    1234	03/03/2013	9	             OUI	RTT
    1234	04/03/2013	10	             OUI	RTT
    1234	05/03/2013	10	             NON	
    1234	06/03/2013	10	             NON	
    1234	07/03/2013	10	             NON	
    1234	08/03/2013	10	             OUI	CP
    1234	09/03/2013	10	             OUI	CP

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 134
    Par défaut
    Tu reprends la requête précédente et tu rajoutes le type dans les condition de regroupement / rupture
    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
    WITH    debut   --  La date de début de période de congés
    AS  (   SELECT  tb1.id_personne
                ,   tb1."type"
                ,   tb1."date"      AS debut
            FROM    matable tb1
            WHERE   tb1.conges  = 'OUI'
                AND NOT EXISTS  -- début si jour = congés et veille != congés
                    (   SELECT  NULL
                        FROM    matable tb2
                        WHERE   tb2.conges      = t1.conges
                            AND tb2."type"      = t1."type"
                            AND tb2.id_personne = tb1.id_personne
                            AND tb2."date"      = tb1."date" -1
                    )
        )
        ,   fin   --  La date de fin de période de congés
    AS  (   SELECT  tb1.id_personne
                ,   tb1."type"
                ,   tb1."date"      AS fin
            FROM    matable tb1
            WHERE   tb1.conges  = 'OUI'
                AND NOT EXISTS  -- fin si jour = congés et lendemain != congés
                    (   SELECT  NULL
                        FROM    matable tb2
                        WHERE   tb2.conges      = t1.conges
                            AND tb2."type"      = t1."type"
                            AND tb2.id_personne = tb1.id_personne
                            AND tb2."date"      = tb1."date" + 1
                    )
        )
        ,   per_debut   -- Numéroter les périodes de congés
    AS  (   SELECT  tb1.id_personne
                ,   tb1."type"
                ,   tb1.debut
                ,   ROW_NUMBER() OVER (PARTITION BY tb1.id_personne, tb1."type" ORDER BY tb1.debut)  AS periode
            FROM    debut   tb1
        )
        ,   per_fin
    AS  (   SELECT  tb1.id_personne
                ,   tb1."type"
                ,   tb1.fin
                ,   ROW_NUMBER() OVER (PARTITION BY tb1.id_personne, tb1."type" ORDER BY tb1.fin)  AS periode
            FROM    debut   tb1
        )
    SELECT  tb1.id_personne
        ,   tb1."type"
        ,   tb1.periode
        ,   tb1.debut
        ,   tb2.fin
    FROM    per_debut   tb1
        INNER JOIN
            per_fin     tb2
            ON  tb2.id_personne = tb1.id_personne
            AND tb2.periode     = tb1.periode       -- Regrouper les périodes
    ;
    Au passage, date et type sont des mots réservés du langaqe SQL et ne devraient pas être utilisés pour nommer des objets.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  7. #7
    Membre averti
    Femme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2013
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 18
    Par défaut
    Super
    Merci pour ta réponse

    Oui oui je sais que "date" et "type" sont des mots clés, c'était juste pour illustrer mon exemple.

Discussions similaires

  1. Réponses: 5
    Dernier message: 18/03/2011, 22h43
  2. [CR XI] Calcul ne nombre de samedi et dimanche pour une période
    Par 007max31 dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 26/08/2009, 16h07
  3. calcul préavis dans le cas d'une période d'essai renouvelée
    Par benlabasse dans le forum Démission
    Réponses: 6
    Dernier message: 22/02/2008, 14h18
  4. [VBA-A] calcul du total des heures d'une période
    Par aibar dans le forum VBA Access
    Réponses: 2
    Dernier message: 11/06/2006, 00h16
  5. Calculer la période d'une horloge
    Par barthelv dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 08/03/2004, 16h39

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