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 :

rownum ne marche pas avec un agrégat


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 137
    Par défaut rownum ne marche pas avec un agrégat
    Bonjour,

    j'ai un bout de requête qui cumule par facture les quantités et le poids et qui fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT (DL.AR_REF || ' / ' || SUM( DL.DL_QTE) || ' / ' || SUM( DL.DL_POIDSNET) / 10 )
    FROM F_DOCLIGNE DL
    GROUP BY DL.AR_REF, DL.DO_PIECE
    HAVING DL.DO_PIECE = 'FC080920'
    AND DL.AR_REF NOT LIKE 'Z%'
    )
    me renvoie par exemple (si je n'ai que deux références sur la facture) :

    A08 / 26 / 364
    A06 / 2 / 200

    Maintenant je n'ai besoin de récupérer que la 1ère ligne, ou la deuxième ligne, ou la 3ième ligne. Rownum fonctionne OK sur un SELECT classique, mais ici

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    select *
    from (
        SELECT (DL.AR_REF || ' / ' || SUM( DL.DL_QTE) || ' / ' || SUM( DL.DL_POIDSNET) / 10 )
        FROM F_DOCLIGNE DL
        GROUP BY DL.AR_REF, DL.DO_PIECE
        HAVING DL.DO_PIECE = 'FC080920'
        AND DL.AR_REF NOT LIKE 'Z%'
    )
    WHERE rownum = 1
    il n'y a que ROWNUM=1 qui fonctionne, qui me renvoie bien la 1ère ligne, 2 ne me renvoie rien du tout, mais si je demande :

    WHERE rownum < 3 j'ai bien les deux !!

    Si quelqu'un a une idée de la manière de faire ça ?

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Mettez rownum dans votre sous-requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT *
    FROM (
        SELECT rownum as rk, (DL.AR_REF || ' / ' || SUM( DL.DL_QTE) || ' / ' || SUM( DL.DL_POIDSNET) / 10 )
        FROM F_DOCLIGNE DL
        GROUP BY DL.AR_REF, DL.DO_PIECE
        HAVING DL.DO_PIECE = 'FC080920'
        AND DL.AR_REF NOT LIKE 'Z%'
    )
    WHERE rk = 2

  3. #3
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Salut Waldar,

    je pense qu'il y a quelque chose qui cloche :

    WHERE dl.do_piece = 'FC080920' AND dl.ar_ref NOT LIKE 'Z%' au lieu

    HAVING DL.DO_PIECE = 'FC080920'
    AND DL.AR_REF NOT LIKE 'Z%' ???

    A ma connaissance le having s'applique pour une condition sur les fonctions de groupes par exemple count(1)>0.

    Cordialement Salim.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 137
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Mettez rownum dans votre sous-requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT *
    FROM (
        SELECT rownum as rk, (DL.AR_REF || ' / ' || SUM( DL.DL_QTE) || ' / ' || SUM( DL.DL_POIDSNET) / 10 )
        FROM F_DOCLIGNE DL
        GROUP BY DL.AR_REF, DL.DO_PIECE
        HAVING DL.DO_PIECE = 'FC080920'
        AND DL.AR_REF NOT LIKE 'Z%'
    )
    WHERE rk = 2
    Ca ne marche pas parce que je dois ajouter rownum à la clause GROUP BY ce qui empêche le regroupement sur AR_REF et DO_PIECE.

    Et rownum dans ce contexte me renvoie ces valeurs :
    RK
    -----
    1920
    1924
    1922

  5. #5
    Membre chevronné Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Par défaut
    Essaye avec cette version :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT *
    FROM (
    SELECT rownum AS rk, col
        SELECT (DL.AR_REF || ' / ' || SUM( DL.DL_QTE) || ' / ' || SUM( DL.DL_POIDSNET) / 10 ) AS col
        FROM F_DOCLIGNE DL
        GROUP BY DL.AR_REF, DL.DO_PIECE
        WHERE DL.DO_PIECE = 'FC080920'
        AND DL.AR_REF NOT LIKE 'Z%'
    ))
    WHERE rk = 2

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    507
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 507
    Par défaut
    Effectivement, le "HAVING" est curieux.
    Que donne ceci?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT facture
      FROM (SELECT ROWNUM, facture
              FROM (SELECT   (   dl.ar_ref
                              || ' / '
                              || SUM (dl.dl_qte)
                              || ' / '
                              || SUM (dl.dl_poidsnet) / 10
                             ) facture
                        FROM f_docligne dl
                       WHERE dl.do_piece = 'FC080920' AND dl.ar_ref NOT LIKE 'Z%'
                    GROUP BY dl.ar_ref, dl.do_piece))
     WHERE rk = 2;
    Edit: grillé!

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Salim, dans le having on peut mettre tous les objets du select (aggrégats et regroupements) :

    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
    With Temp AS
    (
    select 'A' as cd, 1 as nb from dual union all
    select 'A'      , 1       from dual union all
    select 'B'      , 1       from dual union all
    select 'C'      , 2       from dual union all
    select 'D'      , 0       from dual
    )
      select cd, sum(nb) as nb_sum
        from Temp
    group by cd
      having sum(nb) > 1;
     
    CD	NB_SUM
    A	2
    C	2
     
      select cd, sum(nb) as nb_sum
        from Temp
    group by cd
      having cd in ('C', 'D');
     
    CD	NB_SUM
    D	0
    C	2
    Il m'est arrivé une ou deux fois de mettre certains filtres dans la clause having plutôt que dans un where pour changer un plan d'exécution qui passait par un index inadapté.

    Quand on n'a pas la main sur les objets de la base ça peut aider !

    thierrybo, effectivement rownum est évalué avant l'aggrégat et ça ne fonctionnera pas.
    Vous pouvez par contre utiliser row_number() qui lui est évalué après :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT *
    FROM (
        SELECT row_number() over(order by DL.AR_REF asc) AS rk, (DL.AR_REF || ' / ' || SUM( DL.DL_QTE) || ' / ' || SUM( DL.DL_POIDSNET) / 10 )
        FROM F_DOCLIGNE DL
        GROUP BY DL.AR_REF, DL.DO_PIECE
        HAVING DL.DO_PIECE = 'FC080920'
        AND DL.AR_REF NOT LIKE 'Z%'
    )
    WHERE rk = 2

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 137
    Par défaut
    Pour info je poste une solution que je viens de trouver, avant de lire et d'essayer vos solutions depuis le message #5

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT RESULT
    FROM (
     
        SELECT RESULT, row_number() over(order by RESULT) RNUM
        FROM (
            SELECT (DL.AR_REF || ' / ' || SUM( DL.DL_QTE) || ' / ' || SUM( DL.DL_POIDSNET) / 10 ) RESULT
            FROM F_DOCLIGNE DL
            GROUP BY DL.AR_REF, DL.DO_PIECE
            HAVING DL.DO_PIECE = 'FC080920'
            AND DL.AR_REF NOT LIKE 'Z%'
        )
    )
    WHERE RNUM BETWEEN 2 AND 2
    mais ce n'est pas forcément la meilleure !

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

Discussions similaires

  1. [PHP-JS] Marche pas avec le Javascript?
    Par MinsK dans le forum Langage
    Réponses: 3
    Dernier message: 04/05/2006, 14h24
  2. [VB6] TypeOf ne marche pas avec les Label ?
    Par belfaigore dans le forum VB 6 et antérieur
    Réponses: 14
    Dernier message: 21/04/2006, 13h36
  3. [CSS] Bug IE avec height ne marche pas avec les %
    Par El Riiico dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 23/06/2005, 17h11
  4. [xhtml][css] bouton du form ne marche pas avec IE6
    Par chinouk dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 14/06/2005, 14h00
  5. Rollback ne marche pas avec interbase
    Par Tsimplice dans le forum Bases de données
    Réponses: 2
    Dernier message: 09/03/2004, 08h39

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