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 :

GROUP BY: comment "conserver" les champs hors du group by


Sujet :

SQL Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 47
    Points : 30
    Points
    30
    Par défaut GROUP BY: comment "conserver" les champs hors du group by
    Bonjour,

    Soit la table suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    JOINTURE
    IP             ;REGLE          ;NOM
    192.168.000.001;192.168*       ;"réseau local";...
    192.168.000.001;192.168.000*   ;"réseau local / sous réseau 0";...
    192.168.000.001;192.168.000.001;"machine à toto";...
    192.168.000.002;192.168*       ;"réseau local";...
    192.168.000.002;192.168.000*   ;"réseau local / sous réseau 0";...
    192.168.000.002;192.168.000.001;"machine à dede";...
    127.000.000.001;127.000.000.001;"moi-meme"
    NB: le joker * est toujours à la fin de la regle

    Comment obtenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    192.168.000.001;192.168.000.001;"machine à toto";...
    192.168.000.002;192.168.000.001;"machine à dede";...
    127.000.000.001;127.000.000.001;"moi-meme"
    Comme si on faisait un group by sur la colonne IP et que l'on conservait tous les champs associés à la règle la plus discriminante (length(regle) la plus longue)

    Si ça peut aider au lieu de considérer la table jointure, a l'origine j'ai pluôt les 2 tables suivantes
    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
     
    Adresses_IP  
    [IP,...,..]
    192.168.000.001;...
    192.168.000.002;...
    127.000.000.001;...
     
     
    Regles     
    [REGLE,NOM,...]
    192.168*      ;"réseau local";...
    192.168.000*   ;"réseau local / sous réseau 0";...
    192.168.000.002;"machine à toto";...
    192.168.000.001;"machine à dede";...
    127.000.000.001;"moi-meme"


    D'avance merci,

    Vincent

  2. #2
    Rédacteur
    Avatar de Bruno2r
    Homme Profil pro
    Exploitation des données
    Inscrit en
    Décembre 2006
    Messages
    2 566
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Exploitation des données
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 566
    Points : 4 780
    Points
    4 780
    Par défaut
    Bonsoir,
    Je me trompe peut être mais il me semble que la requête suivante devrait suffire ... non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT A.IP, B.REGLE, B.NOM
    FROM Adresses_IP A, Regles B
    WHERE A.IP = B.REGLE

  3. #3
    Expert éminent
    Avatar de pachot
    Homme Profil pro
    Developer Advocate YugabyteDB
    Inscrit en
    Novembre 2007
    Messages
    1 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Developer Advocate YugabyteDB
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 822
    Points : 6 446
    Points
    6 446
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Avec les fonctions analytiques:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select IP,REGLE,NOM from (
     select IP,REGLE,NOM, max(length(REGLE)) over (partition by IP) max_length_regle from JOINTURE
    ) where max_length_regle = length(REGLE)
    Cordialement,
    Franck.

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 394
    Points
    18 394
    Par défaut
    Sans 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
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    WITH ADRESSES_IP AS
    (
    SELECT '192.168.000.001' AS IP FROM DUAL UNION ALL
    SELECT '192.168.000.002'       FROM DUAL UNION ALL
    SELECT '127.000.000.001'       FROM DUAL
    ),
         REGLES AS
    (
    SELECT '192.168*' AS REGLE, 'réseau local'          AS NOM FROM DUAL UNION ALL
    SELECT '192.168.000*'     , 'réseau local / sous réseau 0' FROM DUAL UNION ALL
    SELECT '192.168.000.002'  , 'machine à toto'               FROM DUAL UNION ALL
    SELECT '192.168.000.001'  , 'machine à dede'               FROM DUAL UNION ALL
    SELECT '127.000.000.001'  , 'moi-meme'                     FROM DUAL
    )
    SELECT
        AI.IP,
        MAX(RG.REGLE) KEEP (DENSE_RANK FIRST ORDER BY LENGTH(RG.REGLE) DESC) AS REGLE,
        MAX(RG.NOM)   KEEP (DENSE_RANK FIRST ORDER BY LENGTH(RG.REGLE) DESC) AS NOM
    FROM
        ADRESSES_IP AI
        INNER JOIN REGLES RG
          ON AI.IP LIKE REPLACE(RG.REGLE, '*', '%')
    GROUP BY
        AI.IP;
     
     IP              REGLE           NOM           
    --------------- --------------- ---------------
    127.000.000.001	127.000.000.001	moi-meme
    192.168.000.001	192.168.000.001	machine à dede
    192.168.000.002	192.168.000.002	machine à toto

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 47
    Points : 30
    Points
    30
    Par défaut
    Hello,

    Merci pour toutes ces réponses, je vais les étudier.

    Citation Envoyé par Bruno2r Voir le message
    Bonsoir,
    Je me trompe peut être mais il me semble que la requête suivante devrait suffire ... non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT A.IP, B.REGLE, B.NOM
    FROM Adresses_IP A, Regles B
    WHERE A.IP = B.REGLE
    A priori ta requête me retourne le contenu de la table jointure (soit : pour chaque IP, la liste de toutes les règles correspondantes) moi ce que je souhaitais obtenir c'est la règle la plus restrictive (=la plus longue) pour chaque adresse.

    Vincent.

  6. #6
    Rédacteur
    Avatar de Bruno2r
    Homme Profil pro
    Exploitation des données
    Inscrit en
    Décembre 2006
    Messages
    2 566
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Exploitation des données
    Secteur : Santé

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 566
    Points : 4 780
    Points
    4 780
    Par défaut
    Bonjour,
    Hello,

    Merci pour toutes ces réponses, je vais les étudier.

    Citation Envoyé par Bruno2r Voir le message
    Bonsoir,
    Je me trompe peut être mais il me semble que la requête suivante devrait suffire ... non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT A.IP, B.REGLE, B.NOM
    FROM Adresses_IP A, Regles B
    WHERE A.IP = B.REGLE
    A priori ta requête me retourne le contenu de la table jointure (soit : pour chaque IP, la liste de toutes les règles correspondantes) moi ce que je souhaitais obtenir c'est la règle la plus restrictive (=la plus longue) pour chaque adresse.

    Vincent.
    Je ne crois pas qu'avec une Equijointure A.IP=B.Règle tu récupères la table jointure. En revanche, si on se base sur tes données en exemple on perd Machine à dede

    Puisque (et c'est une chose que je n'avais percuté en lisant trop rapidement ton exemple) les lignes à récupérer n'ont pas toujours IP = Règle (vrai pour toto et moi même, faux pour dede)
    Suis pas sûr que Waldar l'ait vu non plus car il ne l'a pas reproduit dans son exemple

    Autre chose que je n'avais pas devinée c'est que s'il n'y a pas de ligne "machine de..." tu veux sûrement récupérer le sous réseau ... ?

    Dans ce cas et de toute façon la solution de Waldar est vraiment parfaite

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 47
    Points : 30
    Points
    30
    Par défaut
    Bonjour,

    Citation Envoyé par Bruno2r Voir le message
    Bonjour,

    Je ne crois pas qu'avec une Equijointure A.IP=B.Règle tu récupères la table jointure. En revanche, si on se base sur tes données en exemple on perd Machine à dede

    Puisque (et c'est une chose que je n'avais percuté en lisant trop rapidement ton exemple) les lignes à récupérer n'ont pas toujours IP = Règle (vrai pour toto et moi même, faux pour dede)
    Suis pas sûr que Waldar l'ait vu non plus car il ne l'a pas reproduit dans son exemple
    Comme l'avait deviné Waldar la jointure se fait sur AI.IP LIKE REPLACE(RG.REGLE, '*', '%').
    J'aurai du l'écrire dans ma question initiale, cela aurait été plus clair pour tout le monde.

    Autre chose que je n'avais pas devinée c'est que s'il n'y a pas de ligne "machine de..." tu veux sûrement récupérer le sous réseau ... ?
    Exactement. Je veux récupérer tous les champs de la ligne qui contient la règle la plus "précise" (* étant un caractère joker)
    Pour 192.168.000.001 j'ai plusieurs correspondances possibles :
    192.168* ;"réseau local";...
    192.168.000* ;"réseau local / sous réseau 0";...
    192.168.000.001;"machine à toto";...
    La ligne qui m'intéresse est bien "machine à toto".

    Pour une hyptothétique machine 192.168.000.003 j'aurai 2 correspondances possibles
    192.168* ;"réseau local";...
    192.168.000* ;"réseau local / sous réseau 0";...
    Cette fois-ci je souhaite obtenir "sous réseau 0"

    En fait, mon problème ne porte pas sur des réseaux/sous-réseaux/machines mais sur une hiérarchie de catégories comptables.
    J'avais pris l'exemple des réseaux pensant que cela serait plus parlant, sauf que je me suis emmêlé les pinceaux dans les données
    de mes exemples. Bref, désolé pour ceux qui ont peiné à trouver le bon résultat avec de mauvaises données et félicitations (et merci) aux autres.

    Dans ce cas et de toute façon la solution de Waldar est vraiment parfaite
    Ca a l'air en effet.

    Merci à tous.

Discussions similaires

  1. comment ne pas afficher les options dans select group
    Par razily dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 15/03/2012, 16h37
  2. Réponses: 8
    Dernier message: 21/08/2007, 18h07

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