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 :

Requete SQL sur jointure test d'égalité et pas de contenance


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Par défaut Requete SQL sur jointure test d'égalité et pas de contenance
    Le cas est le suivant :

    J'ai une table T3_TABLE_A2 et une jointure T3_JOIN_A2_A2 qui permet aux objets de la table T3_TABLE_A2 de pointer vers eux-mêmes.

    Auparavant il y avait 1 seul champ PK sur la table T3_TABLE_A2 donc je m'en sortais, mais maintenant il y a 2 PK et ca se complique grandement (pour moi).

    je veux les objets de T3_TABLE_A2 qui pointent (à travers la jointure)à vers un objet de T3_TABLE_A2 précis (0,0) ici pour simplifier.

    J'encode avec un moteur ainsi :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        select distinct T3_TABLE_A2.ID, T3_TABLE_A2.SITE_ID 
        from T3_TABLE_A2, T3_JOIN_A2_A2 
        where (((T3_JOIN_A2_A2.ID1=(T3_TABLE_A2.ID)) 
                and (T3_JOIN_A2_A2.SITE_ID1=(T3_TABLE_A2.SITE_ID))) 
                and ((T3_JOIN_A2_A2.ID2=0) 
                and (T3_JOIN_A2_A2.SITE_ID2=0)))

    Ca "marche" mais me retourne trop de résultats : cela retourne tous les T3_TABLE_A2 qui CONTIENNENT mon objet cible (0,0) mais pas qui sont en EGALITE avec cette cible. Ceux qui pointent vers la cible + d'autres valeurs sont aussi retournés (j'ai un filtre contient au lieu d'égale).

    Avec la double clé je ne vois pas trop comment faire : le code ci-dessous ne marche pas (aucun résultat) :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
      select distinct T3_TABLE_A2.ID, T3_TABLE_A2.SITE_ID 
        from T3_TABLE_A2, T3_JOIN_A2_A2 
        where (((T3_JOIN_A2_A2.ID1=(T3_TABLE_A2.ID)) 
                and (T3_JOIN_A2_A2.SITE_ID1=(T3_TABLE_A2.SITE_ID))) 
                and ((T3_JOIN_A2_A2.ID2=0) 
                and (T3_JOIN_A2_A2.SITE_ID2=0))
                and not exists (select * 
        from T3_TABLE_A2, T3_JOIN_A2_A2 
        where (((T3_JOIN_A2_A2.ID1=(T3_TABLE_A2.ID)) 
                and (T3_JOIN_A2_A2.SITE_ID1=(T3_TABLE_A2.SITE_ID))) 
                and ((T3_JOIN_A2_A2.ID2<>0) 
                or (T3_JOIN_A2_A2.SITE_ID2<>0)))))

    avec une seule ID j'encodais ainsi :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select distinct T3_TABLE_A.ID from T3_TABLE_A where 
    (((ID in (select ID1 from T3_JOIN_A_A where (ID2=1))) and not exists (select ID1 from T3_JOIN_A_A LY_5 where (ID2<>1) and (ID=ID1))))
    et ca marchait

    Des idées ?
    Merci

  2. #2
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    C'est l'enfer ton code.. t'aime bien les parenthèses, non ?
    Un peu d'alias simplifierai aussi pas mal
    ton premier code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT DISTINCT t.ID, t.site_id 
    FROM T3_TABLE_A2 t, T3_JOIN_A2_A2 j
    WHERE j.id1	= t.ID
    AND j.site_id1	= t.site_id
    AND j.id2	= 0
    AND j.site_id2	= 0
    peut être transformé en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT ID, site_id
    FROM T3_TABLE_A2 t
    WHERE EXISTS ( SELECT 1 
    		FROM T3_JOIN_A2_A2 j	
    		WHERE j.id1	= t.ID
    		AND j.site_id1	= t.site_id
    		AND j.id2	= 0
    		AND j.site_id2	= 0
    	)
    Et je n'ai pas compris la finalité de ce que tu veux. Peux tu donner un exemple concret, car ta phrase
    (j'ai un filtre contient au lieu d'égale).
    , faudrait l'expliquer

  3. #3
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Ta première requete peut être transformée en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT id1 as id, site_id1 as site_id
    FROM T3_JOIN_A2_A2 	
    WHERE id2	= 0
    AND site_id2	= 0

  4. #4
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Par défaut Suite
    1) Pour les parenthèses et les noms justement je ne les aime pas plus que cela : c'est que mon code génère la requête SQL à partir du modèle Java Objet.

    En passant en Modele Objet ca sera peut etre plus clair:

    Classe A a une relation multiple vers elle même
    (par exemple une personne connait des personnes ...)

    Si j'ai A1 --> A0 et A2 --> A0 et A1

    A1 pointe vers A0 seulement et A2 vers A0 ET vers A1 il y a donc une entrée dans la jointure pour A1 et 2 pour A2

    Je veux les A qui pointent EXACTEMENT vers A0 et A0 seulement (c'est ca que j'appelle un EGAL sur la relation) alors que A2 à une relation qui CONTIENT A0 mais n'est pas EGALE à A0 car il y a aussi A1.

    J'espere que c'est plus clair
    en tout cas merci pour votre réponse.

  5. #5
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Beaucoup plus clair
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT id1 as id, site_id1 as site_id
    FROM T3_JOIN_A2_A2 	
    GROUP BY id1, site_id1
    HAVING count(*)  = 1
    AND min(id2)	= 0
    AND min(site_id2)	= 0

  6. #6
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Par défaut Merci
    Je vais investiquer ce type de syntaxe avec having count() : le pb c'est que je suis aussi obligé de garder
    le SELECT DISTINCT T3_TABLE_A2.ID, T3_TABLE_A2.SITE_ID
    FROM T3_TABLE_A2, T3_JOIN_A2_A2
    car la requete porte sur T3_TABLE_A2.
    Je l'ai simplifiée pour la question mais je dois ramener des champs de T3_TABLE_A2 et j'ai potentiellement des criteres supplémentaires sur ces champs de T3_TABLE_A2 dans le where.

    C'est une interface graphique qui permet à l'utilisateur de saisir un filtre complexe ou simple sur le modele objet et je dois la transcrire en une requete ce qui marche à 99% sauf quelques détails dans ce genre.

  7. #7
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT id, site_id
    FROM T3_TABLE_A2 
    WHERE (id, site_id) IN (SELECT id1, site_id1
    		FROM T3_JOIN_A2_A2 	
    		GROUP BY id1, site_id1
    		HAVING count(*)  = 1
    		AND min(id2)	= 0
    		AND min(site_id2)	= 0)
    J'ai corrigé le code précédent, un WHERE qui n'avait rien à faire là.

  8. #8
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Pour info, tu peux le gérer aussi en MINUS (Attention il fait un distinct)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT t.id, t.site_id 
    FROM T3_TABLE_A2 t, T3_JOIN_A2_A2 j
    WHERE j.id1	= t.ID
    AND j.site_id1	= t.site_id
    AND j.id2	= 0
    AND j.site_id2	= 0
    MINUS
    SELECT t.id, t.site_id 
    FROM T3_TABLE_A2 t, T3_JOIN_A2_A2 j
    WHERE j.id1	= t.ID
    AND j.site_id1	= t.site_id
    AND ( j.id2	<> 0
    OR j.site_id2	<> 0)

  9. #9
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Par défaut MERCI
    Les deux requetes marchent effectivement !

    La première m'oblige à revoir davantage l'encodeur mais à le "bon goût" d'etre aussi valable sur oracle et MySql
    Le minus est plus simple car il s'ajoute juste à ma requete précédente sans 'casser' l'existant mais sous MySql il n'aime pas du tout le minus.
    En tout cas merci pour ces syntaxes !

  10. #10
    Membre averti
    Inscrit en
    Juin 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Juin 2007
    Messages : 58
    Par défaut Complément pour Oracle et MySql
    Pour info j'ai aussi ca qui semble marcher sur Oracle et MySql avec un NOT IN au lieu d'un MINUS
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SELECT t.id, t.site_id 
    FROM T3_TABLE_A2 t, T3_JOIN_A2_A2 j
    WHERE j.id1	= t.ID
    AND j.site_id1	= t.site_id
    AND j.id2	= 0
    AND j.site_id2	= 0
    and (t.id, t.site_id) NOT IN (
    SELECT t.id, t.site_id 
    FROM T3_TABLE_A2 t, T3_JOIN_A2_A2 j
    WHERE j.id1	= t.ID
    AND j.site_id1	= t.site_id
    AND ( j.id2	<> 0
    OR j.site_id2	<> 0))

  11. #11
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Préfère le NOT EXISTS au NOT IN (et ça t'enlève une jointure)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT t.ID, t.site_id 
    FROM T3_TABLE_A2 t, T3_JOIN_A2_A2 j
    WHERE j.id1	= t.ID
    AND j.site_id1	= t.site_id
    AND j.id2	= 0
    AND j.site_id2	= 0
    AND NOT EXISTS (SELECT 1
    		FROM T3_JOIN_A2_A2 j2
    		WHERE j2.id1	= t.ID
    		AND j2.site_id1	= t.site_id
    		AND ( j2.id2	<> 0
    		OR j2.site_id2	<> 0))

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

Discussions similaires

  1. Requete SQL avec jointure sur trois tables
    Par pit2121 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 19/05/2008, 23h07
  2. Requete SQL sur table dbase et date du jour
    Par Jean-François PETIT dans le forum Bases de données
    Réponses: 5
    Dernier message: 29/03/2005, 09h31
  3. Ecrire une requete SQL sur plusieurs lignes
    Par PrinceMaster77 dans le forum ASP
    Réponses: 2
    Dernier message: 15/11/2004, 14h47
  4. requete sql sur un grand nombre d enregistrement
    Par marielaure dans le forum Langage SQL
    Réponses: 5
    Dernier message: 13/08/2004, 11h53
  5. Réponses: 2
    Dernier message: 03/05/2004, 12h13

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