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 :

Objets avec les mêmes composants


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 20
    Par défaut Objets avec les mêmes composants
    Bonjour tout le monde,

    j'ai une table nommée "type_piece" :
    type  piece
    ----- -----
    4012  p1
    4012  p2
    4013  p2
    4111  p1
    4111  p2
    La requête suivante m'affiche les types qui ont des pièces communes avec le "4012", alors que je souhaite récupérer par exemple tous les types qui ont exactement les mêmes pièces que le type "4012" : (càd 4012 et 4111)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      SELECT type.TEV_C_EVOP
           , type.TEV_L_EVOP
        FROM P_TYPE_EVOP_TC type
           , P_PIECES_EVOP_TC piece
       WHERE type.TEV_C_EVOP = piece.TEV_TEV_C_EVOP
         AND piece.TDO_TDO_C_TYP_DOC IN (SELECT TDO_TDO_C_TYP_DOC
                                           FROM P_PIECES_EVOP_TC
                                          WHERE TEV_TEV_C_EVOP = 4012)
         AND type.PROC_PROC_CODE = 3
    GROUP BY type.TEV_C_EVOP
           , type.TEV_L_EVOP;
    Merci d'avance.

  2. #2
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    enfantin

    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
    with type_piece as (
    select 4012 type,  'p1' piece from dual union all
    select 4012,  'p2' from dual union all
    select 4013,  'p2' from dual union all
    select 4111,  'p1' from dual union all
    select 4111,  'p2' from dual)
    select type,collect(piece) pieces
    from type_piece
    group by type
    having collect(piece) = (select collect(piece) from type_piece where type=4012)
     
     TYPE PIECES
    ----- ------------------------------------------------------------
     4012 SYSTPoxbnTMPboOTgQ59n0o2g5A==('p1', 'p2')
     4111 SYSTPoxbnTMPboOTgQ59n0o2g5A==('p1', 'p2')

  3. #3
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 20
    Par défaut
    Merci laurent pour ta réponse rapide
    je sais que c'est enfantin , mais je viens tout juste de commencer

    j'ai donné un simple exemple de données pour me faire comprendre, ma table est déjà remplie,
    c'est quoi "collect"?

    merci

  4. #4
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Sur la même idée avec ListAgg
    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
     
    mni@DIANA> r
      1  WITH type_piece AS (
      2  SELECT 4012 type,  'p1' piece FROM dual union ALL
      3  SELECT 4012,  'p2' FROM dual union ALL
      4  SELECT 4013,  'p2' FROM dual union ALL
      5  SELECT 4111,  'p1' FROM dual union ALL
      6  SELECT 4111,  'p2' FROM dual)
      7  SELECT type, LISTAGG(piece, ';') WITHIN GROUP (ORDER BY piece) pieces
      8  FROM type_piece
      9  GROUP BY type
     10  HAVING LISTAGG(piece, ';') WITHIN GROUP (ORDER BY piece)
     11    = (SELECT LISTAGG(piece, ';') WITHIN GROUP (ORDER BY piece) pieces
     12         FROM type_piece
     13*       WHERE type=4012)
     
          TYPE PIECES
    ---------- ------------------------------
          4012 p1;p2
          4111 p1;p2

  5. #5
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    Citation Envoyé par meryazer Voir le message
    c'est enfantin
    ...
    c'est quoi "collect"?
    c'était ironique, COLLECT est quasi inconnu et extrêment rarement employé (je ne l'ai encore jamais vu). C'est aussi apparu en 10g.

    c'est du code objet, ça retourne une collection d'un type temporaire. Il existe un certain nombre de fonctions / opérateurs / conditions obscures, style IS A SET, MEMBER OF, SUBMULTISET, etc...

    COLLECT a pas mal de bugs et n'est pas trop rapide. Mais ton exemple est vraiment un des très rares cas où COLLECT pourrait se révéler utile :-) En fait c'est exactement l'exemple que j'avais choisi dans mon livre, mais finalement je ne l'ai pas publié car je n'ai pas couvert les TYPES Oracle.

    Sinon il faut faire des NOT EXISTS pour être sûr qu'aucune pièce n'existe que dans un des set.

  6. #6
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Ho bien joué, ça compare vraiment des ensembles !

    J'avais fait un truc comme ça avec GROUP_CONCAT sous MySQL (comme la solution LISTAGG de Mnitu) et ça avait divisé le temps d'exécution par 100... mais conceptuellement ça me dérangeait un peu à cause des trucs du genre JAM BON et JAMBON... (même si le risque est limité par le fait qu'on puisse choisir un délimiteur qui ait peu de chances d'apparaître dans les valeurs).
    (Du coup je pensais ajouter la comparaison de la concaténation des longueurs de chaine )

  7. #7
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 20
    Par défaut
    voici l'erreur que ça donne :

    Error at line 1
    ORA-00904: "COLLECT" : identificateur non valide

    même chose pour "LISTAGG", je précise que je suis sur Oracle 9i,
    ces fonctions sont supportées par 10g et 11g
    une solution pour 9i?

    merci

  8. #8
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    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 461
    Par défaut
    Citation Envoyé par laurentschneider Voir le message
    ça retourne une collection d'un type temporaire.
    C'est très séduisant ce COLLECT, et effectivement d'une syntaxe simplissime, mais c'est quand même frustrant d'être obligé de bricoler pour se débarrasser du nom de constructeur qui fait partie du résultat.
    C'est un peu une verrue sur le visage de Miss France !

    La doc Oracle préconise de faire un CAST pour avoir un résultat fiable, donc il faut créer un type, mais l'inconvénient cosmétique persiste : il y a toujours le nom du type dans le résultat, dont il faut se débarrasser.

  9. #9
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Peut être comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT type,
           count(*) as nb
      FROM type_piece
     where piece in (select piece from type_piece where type = 4012)
     GROUP BY type
    HAVING count(*) = (select count(*) from type_piece where type = 4012)
    Sinon en restant sur l'idée de base, regarde les autres techniques de String Aggregation

  10. #10
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    C'est très séduisant ce COLLECT, et effectivement d'une syntaxe simplissime, mais c'est quand même frustrant d'être obligé de bricoler pour se débarrasser du nom de constructeur qui fait partie du résultat.
    C'est un peu une verrue sur le visage de Miss France !

    La doc Oracle préconise de faire un CAST pour avoir un résultat fiable, donc il faut créer un type, mais l'inconvénient cosmétique persiste : il y a toujours le nom du type dans le résultat, dont il faut se débarrasser.
    Pour la verrue, on peut toujours utiliser une fonction TABLE...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    create type piece_t as object(piece varchar2(5))
    /
    create type piece_coll as table of piece_t
    /
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    WITH type_piece AS (
    SELECT 4012 type,  'p1' piece FROM dual union ALL
    SELECT 4012,  'p2' FROM dual union ALL
    SELECT 4013,  'p2' FROM dual union ALL
    SELECT 4111,  'p1' FROM dual union ALL
    SELECT 4111,  'p2' FROM dual),
    t as (
    SELECT type,cast(collect(piece_t(piece)) as piece_coll) p
    FROM type_piece
    GROUP BY type
    HAVING collect(piece) = (SELECT collect(piece) FROM type_piece WHERE type=4012)
    )
    select type, piece from t,table(t.p)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          TYPE PIECE
    ---------- -----
          4012 p1   
          4012 p2   
          4111 p1   
          4111 p2

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 03/05/2012, 13h35
  2. Réponses: 9
    Dernier message: 25/04/2007, 15h54
  3. Réponses: 3
    Dernier message: 22/12/2005, 00h40
  4. Copier contenu TB_A dans TB_B avec les même champs
    Par snoopy69 dans le forum Access
    Réponses: 3
    Dernier message: 13/10/2005, 16h22
  5. [CONCEPTION MCD] Problème avec les clés composées
    Par fabriceMerc dans le forum Schéma
    Réponses: 3
    Dernier message: 14/02/2005, 09h43

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