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

Firebird Discussion :

Manipulation des générateurs et séquences


Sujet :

Firebird

  1. #1
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 780
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 780
    Par défaut Manipulation des générateurs et séquences
    Bonjour à toutes et à tous.

    Bonne année 2016. Bonne santé. Mes meilleurs vœux !

    Suite à une conversation dans ce sujet : http://www.developpez.net/forums/d15...e/#post8489072
    j'ai demandé comment on pouvait résoudre le problème posé par "Le Néophyte", autrement que par une procédure stockée.
    Comme sa demande est faite pour MySql, je pense, sans trop me tromper, que c'est la seule solution possible dans cet environnement.

    Suite à ma demande, SqlPro donne une solution faisable sous 'Microsoft Sql Server', dont je ne possède pas le SGBD sur mon ordinateur.
    De plus, je ne connais pas du tout cette fonctionnalité qu'est le 'DENSE_RANK()'.

    J'ai l'impression que sous FireBird, on peut résoudre ceci, en utilisant le "generator".
    Je suis arrivé à le faire fonctionné mais je ne suis pas arrivé à remettre les deux générateurs de séquence à zéro sur une rupture de séquence sur le couple (course ; clagen).
    ('clagen' signifie 'classement général').

    Voici ce que j'obtiens :
    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    DROP   DATABASE;
    CREATE DATABASE '..\Data\Base.fdb' page_size 4096 DEFAULT CHARACTER SET ISO8859_1;
     
    -- ===================
    -- création "sequence"
    -- ===================
     
    CREATE SEQUENCE seq$rang;
     
    -- =======================
    -- création table "compet"
    -- =======================
     
    create table compet (
    id       integer   not null primary key,
    prenom   char(10)  not null collate fr_fr,
    course   char(10)  not null collate fr_fr,
    clagen   smallint  not null,
    sexe     char(01)  not null  collate fr_fr
    );
     
    -- ===========================
    -- création tigger 'increment'
    -- ===========================
     
    SET TERM #;
     
    CREATE TRIGGER increment for compet
    active before insert position 0
    as
    begin
      new.id = gen_id(seq$rang, 1);
    END#
     
    SET TERM ;#
     
    -- =======================
    -- insertion dans 'compet'
    -- =======================
     
    insert into compet (prenom, course, clagen, sexe) values ('Marc',       'leMans2005', 1, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Jeanne',     'leMans2005', 2, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Mireille',   'leMans2005', 3, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Bruno',      'leMans2005', 4, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Maurice',    'Monaco2006', 1, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Christian',  'Monaco2006', 2, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Sylvie',     'Monaco2006', 3, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('corinne',    'Monaco2006', 4, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Bernadette', 'Monaco2006', 4, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Elise',      'Monaco2006', 6, 'F');
     
    -- ==================
    -- Vidage de 'compet'
    -- ==================
     
    select * from compet;
     
              ID PRENOM     COURSE      CLAGEN SEXE
    ============ ========== ========== ======= ======
               1 Marc       leMans2005       1 H
               2 Jeanne     leMans2005       2 F
               3 Mireille   leMans2005       3 F
               4 Bruno      leMans2005       4 H
               5 Maurice    Monaco2006       1 H
               6 Christian  Monaco2006       2 H
               7 Sylvie     Monaco2006       3 F
               8 corinne    Monaco2006       4 F
               9 Bernadette Monaco2006       4 F
              10 Elise      Monaco2006       6 F
     
     
    commit;
     
    -- ====================
    -- création "generator"
    -- ====================
     
    CREATE GENERATOR gen$hom;
    CREATE GENERATOR gen$fem;
     
    -- ================
    -- Requête sans CTE
    -- ================
     
    select prenom, course, clagen, sexe,
           case sexe when 'H' then next value for gen$hom else null end as clahom,
           case sexe when 'F' then next value for gen$fem else null end as clafem
    from      compet
    order by course, clagen
    ;
     
    PRENOM     COURSE      CLAGEN SEXE                  CLAHOM                CLAFEM
    ========== ========== ======= ====== ===================== =====================
    Marc       leMans2005       1 H                          1                <null>
    Jeanne     leMans2005       2 F                     <null>                     1
    Mireille   leMans2005       3 F                     <null>                     2
    Bruno      leMans2005       4 H                          2                <null>
    Maurice    Monaco2006       1 H                          3                <null>
    Christian  Monaco2006       2 H                          4                <null>
    Sylvie     Monaco2006       3 F                     <null>                     3
    Bernadette Monaco2006       4 F                     <null>                     4
    corinne    Monaco2006       4 F                     <null>                     5
    Elise      Monaco2006       6 F                     <null>                     6
     
     
    -- ====================
    -- création "generator"
    -- ====================
     
    DROP GENERATOR gen$hom;
    DROP GENERATOR gen$fem;
     
    exit;
     
    Appuyez sur une touche pour continuer...
    On remarque que pour la première course, j'obtiens bien la bonne séquence du classement homme (clahom) et femme (clafem).
    Sauf que je ne sais pas comment le remettre à zéro sur la rupture de séquence.

    Autre point important. Dans le classement général, il y deux fois 4. Autrement dit, il y a deux ex æquo !
    Il faudra aussi que le résultat dans le classement des femmes donne deux fois la valeur '2'.
    Le prochain résultat n'est pas trois, mais quatre.

    @+

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 569
    Billets dans le blog
    65
    Par défaut
    Bonjour et meilleurs vœux

    je vais faire une réponse rapide car je n'ai déjà pas le temps de m'étendre sur le sujet
    avec Firebird 3 la question ne se poserait pas car RANK, DENSE_RANK sont implémentés
    avec les versions inférieures je renvoi vers cette FAQ

    enfin je n'utiliserais pas des Séquences mais de simples variables de contexte

  3. #3
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 780
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 780
    Par défaut
    Salut SergioMaster.

    Merci pour les vœux.

    J'ai découvert le lien que tu m'as communiqué avant que tu me le donnes et à vrai dire, je n'ai rien compris de ce qu'il faut faire. Peu importe.
    Je vais basculer vers FireBird 3 pour faire le test.

    @+

  4. #4
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 780
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 780
    Par défaut
    Salut à tous.

    J'ai effectivement installé FireBird version 3.0.0 et j'ai fait le test.
    Voici le résultat :
    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
    DROP   DATABASE;
    CREATE DATABASE '..\Data\Base.fdb' page_size 4096 DEFAULT CHARACTER SET ISO8859_1;
     
    -- =======================
    -- création table "compet"
    -- =======================
     
    create table compet (
    prenom   char(10)  not null collate fr_fr,
    course   char(10)  not null collate fr_fr,
    clagen   smallint  not null,
    sexe     char(01)  not null collate fr_fr
    );
     
    -- =======================
    -- insertion dans 'compet'
    -- =======================
     
    insert into compet (prenom, course, clagen, sexe) values ('Marc',       'leMans2005', 1, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Jeanne',     'leMans2005', 2, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Mireille',   'leMans2005', 3, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Bruno',      'leMans2005', 4, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Maurice',    'Monaco2006', 1, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Christian',  'Monaco2006', 2, 'H');
    insert into compet (prenom, course, clagen, sexe) values ('Sylvie',     'Monaco2006', 3, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('corinne',    'Monaco2006', 4, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Bernadette', 'Monaco2006', 4, 'F');
    insert into compet (prenom, course, clagen, sexe) values ('Elise',      'Monaco2006', 6, 'F');
     
    -- ==================
    -- Vidage de 'compet'
    -- ==================
     
    select * from compet;
     
    PRENOM     COURSE      CLAGEN SEXE
    ========== ========== ======= ======
    Marc       leMans2005       1 H
    Jeanne     leMans2005       2 F
    Mireille   leMans2005       3 F
    Bruno      leMans2005       4 H
    Maurice    Monaco2006       1 H
    Christian  Monaco2006       2 H
    Sylvie     Monaco2006       3 F
    corinne    Monaco2006       4 F
    Bernadette Monaco2006       4 F
    Elise      Monaco2006       6 F
     
     
    commit;
     
    -- ================
    -- Requête avec CTE
    -- ================
     
    WITH temp AS
    (SELECT prenom, course, clagen, sexe,
            rank() over (partition by course, sexe order by course, clagen) as rang
     FROM   COMPET)
    SELECT  prenom, course, clagen, sexe,
            CASE WHEN Sexe = 'H' THEN rang END AS clahom,
            CASE WHEN Sexe = 'F' THEN rang END AS clafem
    FROM    temp
    order by course, clagen;
     
    PRENOM     COURSE      CLAGEN SEXE                  CLAHOM                CLAFEM
    ========== ========== ======= ====== ===================== =====================
    Marc       leMans2005       1 H                          1                <null>
    Jeanne     leMans2005       2 F                     <null>                     1
    Mireille   leMans2005       3 F                     <null>                     2
    Bruno      leMans2005       4 H                          2                <null>
    Maurice    Monaco2006       1 H                          1                <null>
    Christian  Monaco2006       2 H                          2                <null>
    Sylvie     Monaco2006       3 F                     <null>                     1
    Bernadette Monaco2006       4 F                     <null>                     2
    corinne    Monaco2006       4 F                     <null>                     2
    Elise      Monaco2006       6 F                     <null>                     4
     
     
    exit;
     
    Appuyez sur une touche pour continuer...
    En mettant 'dense_rank()', je n'obtiens pas tout à fait le résultat escompté. La solution est d'utiliser 'rank()' !

    Intéressant comme fonctionnalité, surtout que c'est bien plus simple que de faire une procédure stockée et de gérer les ruptures de séquences.

    @+

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 546
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 546
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    En mettant 'dense_rank()', je n'obtiens pas tout à fait le résultat escompté. La solution est d'utiliser 'rank()' !
    Intéressant comme fonctionnalité, surtout que c'est bien plus simple que de faire une procédure stockée et de gérer les ruptures de séquences.
    Ce sera aussi plus performant
    La différence entre RANK et DENSE_RANK consiste à ce que DENSE_RANK attribue une numérotation contigüe même si le rang qui précède présente des égalités
    Exemple : s'il existe 2 classés 3ème ex-aequo
    RANK donne 1, 2, 3, 3, 5, 6 etc..
    DENSE_RANK donne 1, 2, 3, 3, 4, 5 etc...

  6. #6
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 780
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 780
    Par défaut
    Salut Escartefigue.

    Merci Escartefigue, pour tes explications
    J'ai fait quelques tests et je me suis aperçu de ces différences de fonctionnements.

    @+

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

Discussions similaires

  1. Que pensez-vous des générateurs de doc PHP ?
    Par Nonothehobbit dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 64
    Dernier message: 10/07/2007, 10h17
  2. [xml]manipuler des données xml sous Oracle9i
    Par crazy dans le forum SQL
    Réponses: 7
    Dernier message: 28/02/2004, 11h40
  3. Manipuler des dates...
    Par Ti Jen-tsie dans le forum Langage
    Réponses: 4
    Dernier message: 26/06/2003, 11h46
  4. Manipulation des handle contexte
    Par rockbiker dans le forum DirectX
    Réponses: 1
    Dernier message: 09/05/2003, 18h51
  5. Fonctions de manipulation des chaines et des dates
    Par Fares BELHAOUAS dans le forum Débuter
    Réponses: 3
    Dernier message: 09/11/2002, 22h43

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