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 :

Aggréger dans un listagg ou autre


Sujet :

SQL Oracle

  1. #1
    Membre à l'essai
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Juin 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2017
    Messages : 37
    Points : 23
    Points
    23
    Par défaut Aggréger dans un listagg ou autre
    Bonjour,
    J'aimerais savoir s'il existe une possibilité d'aggréger dans le résultat d'un listagg() les éléments identiques?

    De manière simple j'ai plusieurs noms strictement identiques qui s'affichent dans la cellule mais pour faire plus propre j'aurais aimé les regrouper sous la forme d'un seul nom.

    voici le code que j'ai actuellement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select  distinct  sejour.sejo_num_sej AS num_sej, 
    listagg(medexec.mede_nom_usu, ', ') within group (order by medexec.mede_nom_usu) as executant , 
    listagg(acsa.acsa_code_d, ',') within group (order by acsa.acsa_code_d) AS actes
    Le résultat est sous la forme :

    N° séjour unique Dupont, Dupont, Dupont, Dupont Acte A, ActeB, ActeC, Acte D

    et le résultat désiré est :
    N° séjour unique Dupont Acte A, ActeB, ActeC, Acte D

    J'ai bien envie de placer un group by mais je ne comprends pas encore très bien le fonctionnement.

    Merci de votre aide!

  2. #2
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Il faut passer par une sous-requête à mon avis pour éliminer les doublons

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    with data as
     (select 1 As Code, 1 as key, 'Dupont' as nom from dual union
     select 1 As Code, 2 as key,'Dupont' as nom from dual union
     select 1 As Code, 3 as key,'Durand' as nom from dual union
     select 2 As Code, 4 as key,'GG' as nom from dual union
     select 2 As Code, 5 as key,'Dugland' as nom from dual 
     )
     SELECT code, listagg(nom,',') within group (order by Code)
     from data
     group by code;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    1	Dupont,Dupont,Durand
    2	Dugland,GG
    Avec sous-requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    with data as
     (select 1 As Code, 1 as key, 'Dupont' as nom from dual union
     select 1 As Code, 2 as key,'Dupont' as nom from dual union
     select 1 As Code, 3 as key,'Durand' as nom from dual union
     select 2 As Code, 4 as key,'GG' as nom from dual union
     select 2 As Code, 5 as key,'Dugland' as nom from dual 
     )
     SELECT code, listagg(nom,',') within group (order by Code)
     from 
      (select distinct code, nom
      from data
      )
     group by code;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    1	Dupont,Durand
    2	Dugland,GG

  3. #3
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 074
    Points
    8 074
    Par défaut
    A partir d'Oracle 19c, on peut mettre un DISTINCT dans le LISTAGG.
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  4. #4
    Membre à l'essai
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Juin 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2017
    Messages : 37
    Points : 23
    Points
    23
    Par défaut
    Essayez en groupant par séjour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listagg(medexec.mede_nom_usu, ', ') within group (order by sejour.sejo_num_sej) as executant
    [/QUOTE]

    La notion de order by ne fait-elle pas qu'un ordonnancement?
    J'aurais voulu remplacer le order by par un group by mais il est obligatoire.

    En testant, je n'ai pas d'aggrégation sur le nom au niveau de la liste.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Juin 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2017
    Messages : 37
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    A partir d'Oracle 19c, on peut mettre un DISTINCT dans le LISTAGG.
    A priori je ne suis pas sur un Oracle 19c ou plus car j'ai l'erreur : "ORA-30482: option DISTINCT interdite pour cette fonction"

  6. #6
    Membre à l'essai
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Juin 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2017
    Messages : 37
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par Scriuiw Voir le message
    Il faut passer par une sous-requête à mon avis pour éliminer les doublons
    Autant faire le travail sous Excel je gagnerai du temps.

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Vous pouvez aussi faire du JSON pour des résultats > 4000 CHAR:
    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
    with data as (
        select 1 as sejo_num_sej, 'Dupont' as mede_nom_usu, 'Acte A' as acsa_code_d from dual
        union all
        select 1 as sejo_num_sej, 'Dupont' as mede_nom_usu, 'Acte B' as acsa_code_d from dual
        union all
        select 1 as sejo_num_sej, 'Dupont' as mede_nom_usu, 'Acte B' as acsa_code_d from dual
        union all
        select 1 as sejo_num_sej, 'Durant' as mede_nom_usu, 'Acte B' as acsa_code_d from dual
        union all
        select 1 as sejo_num_sej, 'Durant' as mede_nom_usu, 'Acte C' as acsa_code_d from dual
    )
    select sejo_num_sej as sejour, json_arrayagg(bilan_medecin returning clob) as bilan from (
        select sejo_num_sej, json_object( 'medecin' value mede_nom_usu, 'prestations' value prestations) as bilan_medecin from 
        (
            select sejo_num_sej, mede_nom_usu, json_arrayagg(acsa_code_d order by acsa_code_d returning clob) as prestations
            from 
                (
                    select distinct sejo_num_sej, mede_nom_usu, acsa_code_d from data 
                )
            group by sejo_num_sej, mede_nom_usu
        )
    ) 
    group by sejo_num_sej
    ;

    SEJOUR BILAN
    1 [{"medecin" : "Dupont",
    "prestations" : ["Acte A","Acte B"]
    },
    {"medecin" : "Durant",
    "prestations" : ["Acte B","Acte C"]
    }
    ]

  8. #8
    Membre à l'essai
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Juin 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2017
    Messages : 37
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    Vous pouvez aussi faire du JSON pour des résultats > 4000 CHAR:
    Le souci est que la base de donnée est hébergée donc le seul moyen que j'ai est d'utiliser une interface web et je n'ai que des select autorisés sur une base de données dont je n'ai que très peu d'informations. Donc faire du JSON n'est pas possible non plus. Je travaille dans un environnement contraint.

  9. #9
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Citation Envoyé par Noob_si Voir le message
    Autant faire le travail sous Excel je gagnerai du temps.
    Je ne vois pas en quoi la sous-requête permettant d’éliminer les doublons est un problème
    Il n'y a rien de complexe là-dedans et cela répond à votre besoin...

  10. #10
    Membre à l'essai
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Juin 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2017
    Messages : 37
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par Scriuiw Voir le message
    Je ne vois pas en quoi la sous-requête permettant d’éliminer les doublons est un problème
    Il n'y a rien de complexe là-dedans et cela répond à votre besoin...
    Bonjour, la sous-requête proposée impose que je connaisse d'avance les noms de ce que je comprends. Ce qui n'est pas le cas.
    Peut-être ai-je mal compris la requête aussi.

  11. #11
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Euh non pas du tout, la clause WITH sert uniquement à avoir un jeu de données pour exécuter la requête, vous n'en avez pas besoin dans votre cas

  12. #12
    Membre à l'essai
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Juin 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2017
    Messages : 37
    Points : 23
    Points
    23
    Par défaut
    Citation Envoyé par Scriuiw Voir le message
    Euh non pas du tout, la clause WITH sert uniquement à avoir un jeu de données pour exécuter la requête, vous n'en avez pas besoin dans votre cas
    Dans ce cas je n'ai rien compris à la sous requête suggérée

  13. #13
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 053
    Points : 9 393
    Points
    9 393
    Par défaut
    Cette requete, elle est claire ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     select  distinct  sejour.sejo_num_sej AS num_sej, 
     medexec.mede_nom_usu  , 
     acsa.acsa_code_d 
    from ma_table
    Puis celle-ci :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    With X as ( 
    select  distinct  sejour.sejo_num_sej AS num_sej, 
     medexec.mede_nom_usu  , 
     acsa.acsa_code_d 
    from ma_table 
    )
    select 
     sejour.sejo_num_sej AS num_sej, 
    listagg(medexec.mede_nom_usu, ', ') within group (order by medexec.mede_nom_usu) as executant , 
    listagg(acsa.acsa_code_d, ',') within group (order by acsa.acsa_code_d) AS actes
    from X 
    group by    sejour.sejo_num_sej
    Ceci-dit pas sûr que ça réponde 100% à ton besoin
    Si par exemple la 1ère requete que je donne renvoie un truc comme ci-dessous, tu n'auras pas ce que tu veux. Ici, il faudrait un peu plus d'infos pour t'aider plus.
    En particulier, le fait que les 2 ORDER BY soient différents dans ton 1er exemple, ça me paraît suspect.

    num_sej executant actes
    AAA 111 XXX
    AAA 111 YYY
    AAA 222 XXX
    AAA 222 YYY
    Mais même si cette requête ne correspond pas 100% à ta demande, la gymnastique à faire pour l'adapter devrait être assez simple.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

Discussions similaires

  1. [BCB6] Mettre dans une TForm une autre TForm.
    Par almisuifre dans le forum C++Builder
    Réponses: 17
    Dernier message: 25/11/2006, 07h08
  2. [COM] Trouver des mots dans des PDF et autres documents ?
    Par zyongh dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 02/11/2006, 14h23
  3. Rassembler un code evenement dans un module ou autre
    Par Alpha31 dans le forum Access
    Réponses: 2
    Dernier message: 03/06/2006, 20h23
  4. Fonction dans une fonction et autres pbs
    Par TheRedLed dans le forum Langage
    Réponses: 3
    Dernier message: 27/05/2006, 16h06
  5. Insertion d'XML dans de l'HTML (autre cas)
    Par a028762 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 28/08/2005, 10h13

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