1. #1
    Nouveau Candidat au Club
    Inscrit en
    septembre 2008
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 171
    Points : 0
    Points
    0

    Par défaut Fonction qui crée les périodes compliquée

    Salut,

    Je cherche à créer une fonction qui permet de découper et de créer des lignes

    Exemple :

    J'ai une table exercice qui est caractériser par registre,date_debut , date_fin ,annee

    registre | date_debut | date_fin | annee
    -----------------------------------------------------------------------------------------
    10 | 01/01/2013 | 31/12/2013 | 2013
    10 | 03/02/2013 | 20/10/2013 | 2013

    Résultat attendu : c'est de créer des lignes selon la période (prendre j-1)

    registre | date_debut | date_fin | annee
    ------------------------------------------------------------------------------------------
    10 | 01/01/2013 | 02/02/2013 | 2013
    10 | 03/02/2013 |19/10/2013 | 2013
    10 | 20/10/2013 |31/12/2013 | 2013

    Merci pour vos aides

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

    Informations forums :
    Inscription : août 2008
    Messages : 2 600
    Points : 5 016
    Points
    5 016

    Par défaut

    Avec l'exemple un peu enrichi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    select * from t;
     
      REGISTRE DATE_DEBUT          DATE_FIN          
    ---------- ------------------- -------------------
            10 01/01/2013 00:00:00 31/12/2013 00:00:00
            10 03/02/2013 00:00:00 20/10/2013 00:00:00
            11 01/01/2015 00:00:00 20/08/2015 00:00:00
            11 03/04/2015 00:00:00 31/12/2015 00:00:00
            11 08/11/2015 00:00:00 20/12/2015 00:00:00
            12 01/01/2016 00:00:00 31/12/2016 00:00:00
     
     6 lignes sélectionnées
    Une possibilité :
    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
      with liste_date as (
    select registre, date_debut as dte
      from t
     union all
    select registre, date_fin as dte
      from t 
    ),
           resultat as (
    select registre
         , dte as date_debut
         , case when lead(dte,2) over (partition by registre order by dte) is null
                then lead(dte) over (partition by registre order by dte)
                else lead(dte) over (partition by registre order by dte) - 1
            end as date_fin
      from liste_date
    )
    select * 
      from resultat
     where date_fin is not null
     order by registre, date_debut;
     
      REGISTRE DATE_DEBUT          DATE_FIN          
    ---------- ------------------- -------------------
            10 01/01/2013 00:00:00 02/02/2013 00:00:00
            10 03/02/2013 00:00:00 19/10/2013 00:00:00
            10 20/10/2013 00:00:00 31/12/2013 00:00:00
            11 01/01/2015 00:00:00 02/04/2015 00:00:00
            11 03/04/2015 00:00:00 19/08/2015 00:00:00
            11 20/08/2015 00:00:00 07/11/2015 00:00:00
            11 08/11/2015 00:00:00 19/12/2015 00:00:00
            11 20/12/2015 00:00:00 31/12/2015 00:00:00
            12 01/01/2016 00:00:00 31/12/2016 00:00:00
     
     9 lignes sélectionnées
    PS : code testé sur Oracle, mais je pense qu'il n'y a aucune spécificté et qu'il fonctionnera sur postgre

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    septembre 2008
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 171
    Points : 0
    Points
    0

    Par défaut

    Bonjour,

    Merci pour ta réponse,mais il y a un soucis dans la requête parce que j'ai testé dans postgreSQL , je pense que j'ai pas bien expliqué.

    Voici l'exemple que j'ai pris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select identifiant_registre, date_debut ,date_cloture from  r_exercice where identifiant_registre =2;
    Voici le résultat :
    identifiant_registre date_debut date_fin
    2 1989-02-28 1990-02-27
    2 1988-02-28 1989-02-27
    2 1987-02-28 1988-02-27


    normalement le même résultat devra être retourner , par contre si j'ai deux période qui sont dupliqué dans ce cas il devront être découpé.

    Si j'ai par exemple ce tableau :

    identifiant_registre date_debut date_fin
    -----------------------------------------------------------------------
    2 1989-02-28 1990-02-27
    2 1988-02-10 1989-02-27
    2 1987-02-28 1988-02-27


    Le résultat devra être :

    identifiant_registre date_debut date_fin
    --------------------------------------------------------------------------
    2 1987-02-28 1988/02/09
    2 1988-02-10 1988/02/26
    2 1988/02/27 1989/02/27
    2 1989/02/28 1990/02/27

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    août 2008
    Messages
    2 600
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2008
    Messages : 2 600
    Points : 5 016
    Points
    5 016

    Par défaut

    Est-ce mieux ?
    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
     
      with liste_date as (
    select 'deb' as flag, registre, date_debut as dte, date_fin as fin_courant
      from t
     union all
    select 'fin' as flag, registre, date_fin as dte, NULL
      from t 
    ),
           resultat as (
    select flag
         , registre
         , fin_courant
         , dte as date_debut
         , case when flag = 'deb' 
                 and lead(flag) over (partition by registre order by dte) = 'deb'             
                then lead(dte) over (partition by registre order by dte) - 1
                when fin_courant > lead(dte) over (partition by registre order by dte)
                then lead(dte) over (partition by registre order by dte) - 1
                when flag = 'fin' 
                 and lead(flag) over (partition by registre order by dte) = 'fin'
                then lead(dte) over (partition by registre order by dte)
                else fin_courant            
            end as date_fin
      from liste_date
    )
    select registre, date_debut, date_fin 
      from resultat
     where date_fin is not null
     order by registre, date_debut
     
      REGISTRE DATE_DEBUT          DATE_FIN          
    ---------- ------------------- -------------------
             2 28/02/1987 00:00:00 27/02/1988 00:00:00
             2 28/02/1988 00:00:00 27/02/1989 00:00:00
             2 28/02/1989 00:00:00 27/02/1990 00:00:00
             3 28/02/1987 00:00:00 09/02/1988 00:00:00
             3 10/02/1988 00:00:00 26/02/1988 00:00:00
             3 27/02/1988 00:00:00 27/02/1989 00:00:00
             3 28/02/1989 00:00:00 27/02/1990 00:00:00
     
     7 lignes sélectionnées
    En fait je ne sais pas si postgre gère le date - 1 ou s'il faut utiliser une fonction spécifique genre datesub ou autre.

    [edit] Il faudrait préciser le comportement en cas d'égalité entre une date de début et une autre date de fin d'une autre ligne du registre

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    septembre 2008
    Messages
    171
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 171
    Points : 0
    Points
    0

    Par défaut

    Ticket résolu merci.


    Citation Envoyé par skuatamad Voir le message
    Est-ce mieux ?
    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
     
      with liste_date as (
    select 'deb' as flag, registre, date_debut as dte, date_fin as fin_courant
      from t
     union all
    select 'fin' as flag, registre, date_fin as dte, NULL
      from t 
    ),
           resultat as (
    select flag
         , registre
         , fin_courant
         , dte as date_debut
         , case when flag = 'deb' 
                 and lead(flag) over (partition by registre order by dte) = 'deb'             
                then lead(dte) over (partition by registre order by dte) - 1
                when fin_courant > lead(dte) over (partition by registre order by dte)
                then lead(dte) over (partition by registre order by dte) - 1
                when flag = 'fin' 
                 and lead(flag) over (partition by registre order by dte) = 'fin'
                then lead(dte) over (partition by registre order by dte)
                else fin_courant            
            end as date_fin
      from liste_date
    )
    select registre, date_debut, date_fin 
      from resultat
     where date_fin is not null
     order by registre, date_debut
     
      REGISTRE DATE_DEBUT          DATE_FIN          
    ---------- ------------------- -------------------
             2 28/02/1987 00:00:00 27/02/1988 00:00:00
             2 28/02/1988 00:00:00 27/02/1989 00:00:00
             2 28/02/1989 00:00:00 27/02/1990 00:00:00
             3 28/02/1987 00:00:00 09/02/1988 00:00:00
             3 10/02/1988 00:00:00 26/02/1988 00:00:00
             3 27/02/1988 00:00:00 27/02/1989 00:00:00
             3 28/02/1989 00:00:00 27/02/1990 00:00:00
     
     7 lignes sélectionnées
    En fait je ne sais pas si postgre gère le date - 1 ou s'il faut utiliser une fonction spécifique genre datesub ou autre.

    [edit] Il faudrait préciser le comportement en cas d'égalité entre une date de début et une autre date de fin d'une autre ligne du registre

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

Discussions similaires

  1. Existe-t-il une fonction qui liste les périodes mensuelles ?
    Par clavier12AZQSWX dans le forum Langage SQL
    Réponses: 5
    Dernier message: 16/06/2014, 09h15
  2. Réponses: 4
    Dernier message: 04/05/2007, 22h49
  3. Fonction qui detecte les liens morts
    Par Death83 dans le forum Fichiers
    Réponses: 9
    Dernier message: 17/10/2006, 18h39
  4. fonction qui crée un objet
    Par crossbowman dans le forum C++
    Réponses: 4
    Dernier message: 16/03/2006, 21h23
  5. Fonction qui supprime les espaces
    Par Faith's Fall dans le forum C++Builder
    Réponses: 4
    Dernier message: 03/02/2006, 10h29

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