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

PL/SQL Oracle Discussion :

Reconstruction période en PL/SQL


Sujet :

PL/SQL Oracle

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Reconstruction période en PL/SQL
    Bonjour à tous,

    je viens vers vous pour une aide en vue d'ecrire un procédure PL/SQL et j'avoue avoir bien du mal avec les curseurs.
    Le but est de reconstruire des périodes
    j'ai une table avec un nom, un debut et une fin

    NOM ;DEBUT ;FIN
    -------------;----------;----------
    toto ;11/03/2013;23/03/2013
    toto ;24/04/2013;29/04/2013
    toto ;30/04/2013;06/05/2013
    toto ;07/05/2013;06/06/2013

    le but est de recuperer la date de debut et la plus grande date de fin tant que la date de debut suivante-1 est egale à la date de fin precedente.
    dans ce cas precis on doit obtenir

    NOM ;DEBUT ;FIN
    -------------;---------------;----------
    toto ;11/03/2013;06/06/2013

    en vous remerciant de votre aide

    Olivier

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    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 080
    Points : 30 789
    Points
    30 789
    Par défaut
    Montre nous ce que tu commencé à faire, nous pourrons t'aider à le corriger.
    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.

  3. #3
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Sinon, tu as juste le message précédent
    http://www.developpez.net/forums/d14...e/#post8076498
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonjour à tous,

    je n'ai pas écris de procédure pl/SQL. Je l'ai fait un peu a l'image du lien transmis par McM, en sql pur.
    Je reconstruis les periodes dans une nouvelle table en faisant transiter les lignes par une table temporaire. Une fois la ligne détectée, je la tag et la supprime de la table source. Le problème est que pour chaque individu je peux avoir un tres grand nombre d'occurences représentant parfois plusieurs périodes distinctes (si FIN-DEBUT >=2 alors nouvelle période ) et je suis obligé de contrôler visuellement a chaque fois l'etat de ma table source pour savoir si je dois continuer a faire tourner le script ou pas. C'est pour cela que je pense que la solution passe obligatoirement par un langage procédural. je n'ai pas le choix que de le faire en pl/sql sinon je l'aurai attaqué en php mais je peux pas l'interfacer avec Oracle.

    Merci a tous

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Février 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Février 2015
    Messages : 3
    Points : 3
    Points
    3
    Par défaut reponse Sql
    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
     
    WITH Periodes AS
      (SELECT 'toto' nom,
        to_date('11/03/2013','DD/MM/YYYY') datDeb,
        to_date('23/03/2013','DD/MM/YYYY') datFin
      FROM dual
      UNION
      SELECT 'toto' ,
        to_date('24/04/2013','DD/MM/YYYY'),
        to_date('29/04/2013','DD/MM/YYYY')
      FROM dual
      UNION
      SELECT 'toto' ,
        to_date('30/04/2013','DD/MM/YYYY'),
        to_date('06/05/2013','DD/MM/YYYY')
      FROM dual
      UNION
      SELECT 'toto' ,
        to_date('07/05/2013','DD/MM/YYYY'),
        to_date('06/06/2013','DD/MM/YYYY')
      FROM dual
      UNION
      SELECT 'toto' ,
        to_date('17/07/2013','DD/MM/YYYY'),
        to_date('19/07/2013','DD/MM/YYYY')
      FROM dual
      UNION
      SELECT 'toto' ,
        to_date('20/07/2013','DD/MM/YYYY'),
        to_date('08/09/2013','DD/MM/YYYY')
      FROM dual
      ),
      RuptPeriod AS
      (SELECT nom,
        datDeb,
        datFin,
        lead(datDeb)over (partition BY nom order by datDeb)datDebSuiv,
        lag(datFin)over (partition BY nom order by datDeb) datFinPrec,
        CASE
          WHEN datDeb-1= lag(datFin)over (partition BY nom order by datDeb)
            /*date de debut suivante-1 est egale
            ** à la date de fin precedente => tjs meme period
            */
          THEN 0
            /*pour le 1ere periode datFinPrec est
            ** null et on passe au else
            */
          ELSE 1
            /*
            **debut nouvelle periode
            */
        END DebPeriod
      FROM periodes
      ),
      DatIntervPeriod AS
      (SELECT nom,
        datDeb,
        datFin,
        datDebSuiv,
        debPeriod,
        SUM(debPeriod) over (partition BY nom order by datDeb) numPeriod
        /*la somme(1 si debut periode 0 sinon) 
        **  donne numPeriod : numero intervalle contigü
        */
      FROM RuptPeriod
      )
    SELECT nom,
      numPeriod,
      /* MIN(datDeb) et MAX(datFin) sur partition nom et numPeriod
      ** donne debut et fin des intervalles contigüs
      */
      MIN(datDeb)debIntervPeriod,
      MAX(datFin) datFinIntervPeriod
    FROM DatIntervPeriod
    GROUP BY nom,
      numPeriod
    ORDER BY nom,numPeriod

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    NOM   NUMPERIOD DEBINTERVPERIOD DATFININTERVPERIOD
    ---- ---------- --------------- ------------------
    toto          1 11-MAR-13       23-MAR-13          
    toto          2 24-APR-13       06-JUN-13          
    toto          3 17-JUL-13       08-SEP-13

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Octobre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4
    Points : 5
    Points
    5
    Par défaut Reconstruction période
    J'ai eu la même chose à faire mais avec 1 jour d'écart. Fin d'une période le jour J et début de la suivante, le jour J+1.
    Comme j'ai vu un tas de réponses (souvent) compliquées ou avec beaucoup de lignes sur le net, je mets la mienne + simple / + lisible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT aa.X, aa.Y, aa.Z, MIN(aa.datdbt) minDatDbt, MAX(aa.datfin) maxDatFin
    FROM TABLE aa
    WHERE EXISTS (SELECT 1 FROM TABLE b
                     WHERE 
                    (b.datdbt - 1 = aa.datfin OR b.datfin + 1 = aa.datdbt)
                     AND aa.Z = b.Z AND aa.Y = b.Y AND aa.X = b.X
                  )
    GROUP BY aa.X, aa.Y, aa.Z
    ORDER BY aa.X, aa.Y, aa.Z;
    Le GROUP BY et le ORDER BY sont à changer à souhait

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    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 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par oliv5658 Voir le message
    Bonjour à tous,

    je viens vers vous pour une aide en vue d'ecrire un procédure PL/SQL et j'avoue avoir bien du mal avec les curseurs.
    Le but est de reconstruire des périodes
    j'ai une table avec un nom, un debut et une fin

    NOM ;DEBUT ;FIN
    -------------;----------;----------
    toto ;11/03/2013;23/03/2013
    toto ;24/04/2013;29/04/2013
    toto ;30/04/2013;06/05/2013
    toto ;07/05/2013;06/06/2013

    le but est de recuperer la date de debut et la plus grande date de fin tant que la date de debut suivante-1 est egale à la date de fin precedente.
    dans ce cas precis on doit obtenir

    NOM ;DEBUT ;FIN
    -------------;---------------;----------
    toto ;11/03/2013;06/06/2013

    en vous remerciant de votre aide

    Olivier
    Une simple requête suffit. Cela s'appelle une agrégation d'intervalle. Lis les article que j'ai écrit à ce sujet :
    https://blog.developpez.com/sqlpro/p...alles_en_sql_1

    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/ * * * * *

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Octobre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    [QUOTE=Arniol07;10016050]

    La solution, que j'ai fournie précédemment, ne fonctionne pas s'il y une période "creuse" entre des groupes de périodes contiguës.
    Voici une requête trouvée sur le net, qui donne à la fois les périodes indépendantes et les groupes de périodes contiguë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
     
    select X, Y, Z, ZZ, MAX(datcre) maxDatCre, MIN(datdbtvld) minDatDbtVld, MAX(datfinvld) maxDatFinVld
    from
    (
      select 
          X, Y, Z, ZZ, datcre, datdbtvld, datfinvld,
          max(contig) over (partition by X|| Y|| Z|| ZZ order by datfinvld) contiguous_group
      from
        (
        select 
            X, Y, Z, ZZ, datcre, datdbtvld, datfinvld,
            case 
                when lag(datfinvld) over (partition by X|| Y|| Z|| ZZ
                      order by datfinvld) != datdbtvld-1 or row_number() over (partition by X|| Y|| Z|| ZZ order by datfinvld)=1 
                then row_number() over (partition by X|| Y|| Z|| ZZ order by datfinvld) else null end contig
        from xxcus.SELOLT_H_TMP_RDO_MANDAT_REPT
        )
    )
    group by X, Y, Z, ZZ, contiguous_group
        ;
    La concaténation de X|| Y|| Z|| ZZ correspond à mon ID.

Discussions similaires

  1. Période de date SQL dans un scriptshell
    Par Psuchoo dans le forum Sql*Plus
    Réponses: 15
    Dernier message: 27/04/2015, 02h32
  2. SQL : Grouper par période
    Par yvesagha dans le forum Firebird
    Réponses: 2
    Dernier message: 06/09/2010, 18h48
  3. [MySQL] reconstruction d'une requete sql en utilisant php
    Par joulive dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 08/04/2010, 09h39
  4. Requetes sql sur DATE (selection d'une période)
    Par Ma2x. dans le forum Requêtes
    Réponses: 3
    Dernier message: 06/01/2010, 18h25
  5. [SQL SERVEUR 2005] DATE DERNIERE RECONSTRUCTION
    Par Elessar dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 05/11/2007, 21h05

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