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

Langage SQL Discussion :

Comment savoir si un sous ensemble est contenu dans ensemble


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut Comment savoir si un sous ensemble est contenu dans ensemble
    Bonjour,

    Voilà je bute sur une requête SQL : Admettons que j'ai une table avec 2 foreign key (FK1, FK2) et d'autres colonnes.
    Je sais qu'une contrainte d'unicité sur le couple (FK1, FK2) a lieu.
    Je recherche donc toutes les les lignes de la table tel que par exemple le couple (1,3) soit présent dans l'ensemble des couples de la table qui sont par exemple {(3,1),(1,3),(2,1)}. Dans mon exemple, une ligne sera donc retournée.
    Je bute sur cette requête.

    NB : il s'agit d'ensemble ordonné (1,3) et pas (3,1).

    Merci de votre aide

  2. #2
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    il faudrait la description des tables. Un script serait le mieux...

  3. #3
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    Je parle juste d'une simple table avec 2 FK et une contrainte d'unicité sur ces 2 FK.
    Je ne pense pas qu'il y ait besoin d'en savoir plus sur la table.
    Je m'intéresse à la requête SQL, je ne parle pas de script PL/SQL...

    Est-ce possible ?

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 099
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 099
    Points : 28 403
    Points
    28 403
    Par défaut
    Un script désigne un assemblage de commandes dans un langage quelconque.
    En SQL, un script peut être une série de requêtes SQL, voire une seule... et pas obligatoirement du langage procédural.

    Donnez-nous une ébauche de votre requête, nous vous aiderons à la corriger.

  5. #5
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    ben... si tu cherches (FK1 , FK2) = (1, 3)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select ...
    from matable
    where FK1 = 1
    and FK2 = 3

  6. #6
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    Hum, j'ai du mal m'expliquer, je reprends.

    Soit la table A1 : PK1 champ1
    Soit la table A2 : PK2, champ1
    Soit la table B : FKB1 ref PK1, FKB2 ref PK2, champ1 + contrainte d'unicité sur la couple (PKB1,PKB2)
    Soit la table C : FKC1 ref PK1, FKC2 ref PK2, champ1+ contrainte d'unicité sur la couple (PKC1,PKC2)
    Soilt E un ensemble de paire (FK1, FK2)

    Question : A partir d'un ensemble de ligne de C, retourner un ensemble de ligne de B tel que pour chaque ligne de B retournée, la paire ordonnée (FKB1, FKB2) soit présente dans au moins une ligne de C.

    OK ?

    Exemple :

    Contenu de la table A1 :

    1,'toto'
    2,'titi'
    3,'tyty'

    Contenu de la table A2 :

    2,'toto'
    1,'titi'
    3,'tyty'

    Contenu de la table B :
    3,2,'toto'
    3,1,'toto'
    1,3,'toto'

    Contenu de la table C :
    2,1,'toto'
    3,1,'toto'
    2,3,'toto'

    Si je donne en entrée l'ensemble des lignes de la table C, la requête me retourne la ligne 3,1,'toto'

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

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Renseigne-toi sur les jointures.
    (C'est le basique du SQL : tu dois pouvoir trouver des tutoriaux sur ce forum).

    Exemple :
    TableA(Col1, Col2)

    TableB(Col2, Col3)

    Dans TableA, Col2 est la FK vers TableB.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT a.Col1, a.Col2
    FROM TableA a JOIN TableB b
        ON a.Col2 = b.Col2
    => La jointure, c'est le sous-ensemble du produit cartésien respectant la proposition :
    (w,x,y,z) tel que (w,x) € TableA, (y,z) € TableB et x = y

    C'est ce que tu veux ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    Merci mais je connais les jointures.

    Question : où figure la liste fournie en entrée dans ton code ? : "A partir d'un ensemble de ligne de C"

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

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT B.*
    FROM C JOIN B 
        ON C.Col1 = B.FK1
       AND C.Col2 = B.FK2
    Et là ?

  10. #10
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    Tu vois que ce n'est pas simplement une table avec 2 clefs...

    tu devrais essayer avec un "exists" ;o)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select ...
    from B
    where exists(  select 1
    				from C
    				where B.FKB1 = C.FKC2
    				and B.FKB2 = C.FKC2)
    edit : avec la contrainte d'unicité, la solution de pacman est meilleure.

  11. #11
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    On y est presque :

    Donc OK pour la jointure. Imaginez (bon dans mon exemple ça ne retourne que le couple (3,1)) que ça retourne plusieurs resultat (3,1,"toto"), (3,2,"titi").
    Donc j'ai bien c'est 2 entrée dans mes 2 tables. Je cherche maintenant à restreindre ce résultat en fournissant un ensemble en entrée qui contient par exemple (3,1,"toto"). Par conséquent les lignes retournées seront dans B, dans C et dans cet ensemble d'entrée.

    Compris ?

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

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    C'est exactement la clause where

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    WHERE C.col1 = ...
        AND C.col2 = ...
    Toutes les initations au SQL devraient se dérouler dans cet ordre

  13. #13
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    C correspond à la table C chez toi, pas à un ensemble d'entrée.
    Ceci dit, le but finale était de trouver la requête en JPQL/HQL, et ça marche !

    A titre informatif, voici la réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Select cm
    from ConformiteLignePosition cm 
    where  CONCAT(str(cm.id.compte.icompte), str(cm.id.instrumentMarche.ivalpla)) in (:idList) 
    and CONCAT(str(cm.id.compte.icompte), str(cm.id.instrumentMarche.ivalpla)) in
            (Select CONCAT(str(cm.id.compte.icompte), str(cm.id.instrumentMarche.ivalpla)) 
             from LigneComptePositionDeGestion lc 
             where cm.id=lc.id)
    Merci à tous

  14. #14
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    C'est lent avec concat, tu te prives des indexs sur tes colonnes, et en plus, ça peut être faux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     concat('hop', 'la') = concat('ho', 'pla')
    Mieux vaut faire de l'ensembliste.

  15. #15
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    Très juste ! Bien vu "l'effet de bord" ...mais il suffit d'ajouter un séparateur.
    Cependant, la requête que je souhaiterais vraiment est celle-ci générée par Hibernate :

    Hibernate:
    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
        select
            conformite0_.CMDICOMPTE as CMDICOMPTE4_,
            conformite0_.CMDIVALPLA as CMDIVALPLA4_,
            conformite0_.CMDBCONFMD as CMDBCONFMD4_,
            conformite0_.CMDBCONFMR as CMDBCONFMR4_,
            conformite0_.CMDIMODVSN as CMDIMODVSN4_,
            conformite0_.CMDIPOCHE as CMDIPOCHE4_,
            conformite0_.CMDTECAPDS as CMDTECAPDS4_,
            conformite0_.CMDTPOCFIN as CMDTPOCFIN4_ 
        from
            FPMGCMD conformite0_ 
        where
            (
                conformite0_.CMDICOMPTE , conformite0_.CMDIVALPLA
            ) in (
                ? , ? , ?
            )
    Elle est très juste mais si je l'éxecute sur ma base Derby, ça pète ! à cause de la virgule dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (
                conformite0_.CMDICOMPTE , conformite0_.CMDIVALPLA
            )
    2008-06-03 11:47:18,253 | WARN | org.hibernate.util.JDBCExceptionReporter.logExceptions | SQL Error: -1, SQLState: 42X01
    2008-06-03 11:47:18,253 | ERROR | org.hibernate.util.JDBCExceptionReporter.logExceptions | Erreur de syntaxe : Encountered "," at line 1, column 390.

  16. #16
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 099
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 099
    Points : 28 403
    Points
    28 403
    Par défaut
    Utilise EXISTS plutôt que IN

  17. #17
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    Et comment tu transformes la requête avec EXIST ?

  18. #18
    Membre confirmé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Points : 601
    Points
    601
    Par défaut
    C'est de l'hibernate ça, pas du SQL ^^ On te la dit précédement, il faut faire du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    where col1=... and col2=...
    A toi d'adapter ça à hibernate (que je ne connais pas assez pour t'aider... que signifie les "? , ? , ?" ?).



    edit : la requête avec exists, je l'ai montré plus haut ^^

  19. #19
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    Je vais tenter le EXISTS mais je vois mal comment tu pouvais m'aiguiller sur le choix de l'un plutôt que l'autre...suite à la lecture de ce très bon article d'oracle :

    http://oracle-online-help.blogspot.c...st-in-sql.html

    Merci

Discussions similaires

  1. Comment savoir si un fichier/répertoire est en lecture seule
    Par Guigui_ dans le forum Général Python
    Réponses: 3
    Dernier message: 29/12/2004, 16h05
  2. Réponses: 9
    Dernier message: 08/12/2004, 14h36
  3. Comment savoir si une impression s'est bien déroulé?
    Par Cyrilh7 dans le forum C++Builder
    Réponses: 5
    Dernier message: 19/11/2003, 20h49
  4. [VB6] comment savoir si la commande shell est terminée ?
    Par ghyscharlotte dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 30/07/2003, 19h12
  5. Réponses: 4
    Dernier message: 10/09/2002, 17h09

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