Requête SQLite

Salut,



Je manipule SQLite depuis pas mal de temps mais là  je sèche sur une requête toute bête.



Je veux obtenir tous les records de la table A qui ne sont pas liés à  la table B.



En gros, le contraire de INNER JOIN.



Pour obtenir tous les records de la table 1 qui sont associés à  la table 2:





SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.table1_id




Et bien, je veux le contraire: tous les records de la table 1 sans association.



J'ai regardé du côté de LEFT OUTER JOIN et CROSS JOIN, et même UNION, mais ça n'a pas l'air adapté.



Merci.

Réponses

  • J'ai balancé mes cours de SQL il me semble, dommage...
  • Un truc du genre
    <br />
    SELECT * FROM table1 WHERE table1.id NOT IN (SELECT DISTINCT table1_id FROM table2)<br />
    
  • muqaddarmuqaddar Administrateur
    Merci !

    Je vasi regarder ça, je ne connaissais pas NOT IN.
  • Je ne suis pas sûr que l'opérateur IN existe en SQLite. Si ce n'est pas le cas il faut voir du côté des opérateurs EXCEPT, ou EXISTS. Cela m'étonnerait qu'il n'y ait pas au moins un de ces opérateurs.
  • 'jpimbert' a écrit:


    Je ne suis pas sûr que l'opérateur IN existe en SQLite. Si ce n'est pas le cas il faut voir du côté des opérateurs EXCEPT, ou EXISTS. Cela m'étonnerait qu'il n'y ait pas au moins un de ces opérateurs.


    Je me réponds à  moi-même.

    J'ai un peu farfouillé. A priori tous ces opérateurs existent en SQLite. Ma proposition devrait marcher.
  • muqaddarmuqaddar Administrateur
    janvier 2013 modifié #7
    Je te confirme que ça marche.

    J'avais déjà  utilisé IN auparavant, mais pas NOT IN.



    Merci en tout cas, c'est parfait !
  • 'muqaddar' a écrit:


    J'avais déjà  utilisé IN auparavant, mais pas NOT IN.


    J'ai simplement farfouillé dans la doc SQLite
  • AliGatorAliGator Membre, Modérateur
    Par contre faire des requêtes imbriquées (un SELECT dans un autre SELECT) marche mais n'est en général pas ce qui est le plus optimisé, c'est à  réserver pour quand on n'a pas trop d'autre choix en général il me semble (par exemple préférer les jointures quand c'est possible)



    Du coup par exemple une jointure de type LEFT JOIN devrait te retournes toutes les lignes de la table de gauche, même si elles n'ont pas de correspondance dans la table de droite (et dans ce cas pour les champs de la table de droite, au lieu d'avoir le contenu de la ligne correspondante dans cette table puisqu'il n'en aura pas trouvé, toutes les colonnes seront à  NULL).



    A partir de là , je pense que tu peux combiner du coup un "table1 LEFT JOIN table2" avec un "WHERE table2.id = NULL" pour ne garder que les lignes de table1 dont il n'y a pas de correspondance dans table2
    SELECT table1.* FROM table1<br />
    LEFT JOIN table2 ON table1.id = table2.table1_id<br />
    WHERE table2.id = NULL
    
    J'ai pas testé mais ça devrait marcher aussi, et je pense que vu comme en SQL les JOIN sont pas mal optimisés, en tout cas bien plus je pense que les sous-requêtes façon "SELECT dans un SELECT", je pense que ça sera plus efficace.
  • muqaddarmuqaddar Administrateur
    février 2013 modifié #10
    J'ai déjà  pas mal de LEFT JOIN et INNER JOIN dans la même requête (qui est bien plus complexe en fait).



    Bref, j'ai testé dans une requête simple ce que tu dis Ali, ça ne marche pas.

    Pas d'erreur de requête, mais ça ne renvoie rien.



    J'ai juste modifié "WHERE table2.id = NULL" pour "WHERE table2.id IS NULL"...



    Le NOT IN semble être la seule solution pour mon cas.



    EDIT: ça a l'air de marcher finalement, il fallait que je jongle avec d'autres champs (status).
  • AliGatorAliGator Membre, Modérateur
    Oui faire le test de NULL sur le table2.id n'était peut-être pas la meilleure idée vu que c'est le champ sur lequel on fait la jointure et qu'il peut donc peut-être inférer sa valeur de table1.table2_id (ou vice-versa je sais pas dans quel sens tu as fait la jointure ^^), alors que les autres champs eux seront bien NULL...
  • LeChatNoirLeChatNoir Membre, Modérateur
    et le minus ? Ca existe pas ?
Connectez-vous ou Inscrivez-vous pour répondre.