6
votes

Joindre intérieur où ** Chaque rangée ** doit correspondre à la clause WHERE?

Voici un exemple simplifié de ce que j'essaie de faire. J'ai deux tables, A et B.

SELECT * from A INNER JOIN B on B.a_id = A.id WHERE B.value > 2


3 commentaires

Pouvez-vous modifier votre question et fournir des échantillons de données et des résultats souhaités?


Votre définition est contradictoire . Si vous avez plus d'une valeur distincte dans a.id il est impossible pour toutes les lignes de B correspondent à ce que , car une ligne dans B ne peut avoir plus d'une valeur à la fois. Précisez s'il vous plaît. Il semblerait que vous voulez dire: renvoie toutes les lignes de A , où toutes les lignes dans B correspondant sur b.a_id = a.id remplit également la deuxième condition b.value> 2 .


Vous avez raison, @erwinbrandsetter, j'ai eu la contrainte que b.a_id = a.Id à l'esprit. Édité pour clarifier.


7 Réponses :


8
votes
SELECT  *
FROM    a
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    b
        WHERE   b.a_id = a.a_id
                AND (b.value <= 2 OR b.value IS NULL)
        )

1 commentaires

Vous pouvez également écrire la requête comme celle-ci si vous avez choisi d'utiliser Existe logique sur jointure Sélectionnez * à partir d'un endroit où il n'existe pas (sélectionnez 1 de b où b.a_id = a.a_idand (ifnull (ifnull ( b.value, 0) <= 2)



1
votes

Essayez ceci xxx


9 commentaires

Cela retournera une ligne s'il n'y a qu'une entrée unique dans B qui correspond au filtre pour a_id , quelles que soient les autres entrées qui ne le font pas


Cette requête doit renvoyer tous les enregistrements dans A qui n'existe pas en B et que la valeur> 2 est ce que l'OP demande


L'OP demande que Tous Les lignes de B correspondent au . Votre requête reviendra si Toute ligne dans B correspond au ou s'il n'y a pas de lignes dans B pour Ce a_id .


Je ne sais pas si j'ai mal compris les 2 conditions "1.) Toutes les lignes de B correspondent à l'endroit où, ou 2), il n'y a pas de rangées en B qui référence a"


Dis qu'il y a deux entrées dans b (a_id, valeur) : (1, 1), (1, 3). Op ne veut pas a_id = 1 pour revenir.


2) Il n'y a pas de lignes en B que référence a Dis-moi qu'il veut toute la ligne de B s'il n'y a pas de match dans B + rien qui a une correspondance en B, mais a une valeur> 2 si Ce n'est pas que l'OP demande que je suggère de mettre un jfiddle avec des données factices afin que nous sachions quoi recommander


Je veux seulement sélectionner la ligne à partir d'un si tous les lignes de B de B que référence a ont une valeur> 2. ou s'il n'y a pas de lignes de B de B de ce qui référence A.


@jhickner ma requête devrait faire juste ça. S'il vous plaît donnez-lui un coup de feu, laissez-moi savoir le résultat. Vous devez mettre d'exemple de données et vos résultats attendus dans votre question


Pas ça ne le fait pas. Vous retournez toutes les colonnes d'A et B, éventuellement plusieurs combinaisons (multiplication a), irrégulière de savoir s'il ya des lignes incriminées en B pour le même A_ID. Cela ne pourrait pas me tromper.



1
votes
SELECT * FROM A LEFT JOIN B ON b.a_id = a.id
WHERE B.a_id IS NULL OR NOT EXIST (
        SELECT  1
        FROM    b
        WHERE  b.value <= 2) 

3 commentaires

Ceci est une syntaxe invalide (pas de condition de jointure).


An maintenant c'est une logique invalide :) Toute ligne unique avec B.Value = 1 supprimerait toutes les lignes d'A avec Tout correspondant correspond à B sur B.A_ID = A .Id .


1.) Toutes les lignes de B correspondent à l'endroit où, ou (dans ce cas si B.Value = 1, toutes les lignes de B correspondent à ce que) de sorte qu'il essaiera de faire le second cas vrai 2.) Il y a Pas de lignes en B qui référence a, ..... où il n'y a pas de ligne faisant référence à une signification B.A_ID est null. C'est ce que les exigences sont dans la question !!



0
votes
SELECT a.is, a.name, c.id as B_id, c.value from A 
INNER JOIN (Select b.id, b.a_id, b.value from B WHERE B.value > 2) C
on C.a_id = A.id 
Note it is a poor practice to use select *. You shoudl only specify fields you need. IN this case, I might possibly remove the b.Id refernces becasue they are probably not needed. If you have a join there is a 100% chance you are wasting resouces sending data you don't need becasue the join fields will be repeated.  That is why I did nto include a_id in the final result set.

0 commentaires

2
votes

Cela devrait résoudre votre problème:

SELECT *
FROM a
WHERE NOT EXISTS (SELECT * 
                  FROM   b 
                  WHERE  b.a_id = a.id
                  AND    (b.value > 2) IS NOT TRUE)          


1 commentaires

Seul NULL n'est pas considéré.



0
votes

Si vous préférez ne pas utiliser Existe , vous pouvez utiliser une jointure externe. XXX

Ceci fonctionne en recherchant l'existence d'un enregistrement d'échec dans B . S'il en trouve un, alors la jointure correspondra et la dernière où la clause exclut l'enregistrement.


1 commentaires

Seul NULL n'est pas considéré.



1
votes

Répondre à cette question (qu'il semble que vous vouliez réellement demander):

retourner toutes les lignes de A code>, où toutes les lignes dans B code> avec b.a_id = a.id code> transmettez également le test b.value> 2 code>. em> p>

qui équivaut à: p>

retournez toutes les lignes de A code>, où aucune ligne dans B code> avec b.a_id = a.id code> échoue le test code> Code> B.Value> 2 CODE>. EM> P>

SELECT a.*  --  "rows from A" (so don't include other columns)
FROM   a
LEFT   JOIN b ON b.a_id = a.id
             AND (b.value > 2) IS NOT TRUE -- safe inversion of logic
WHERE  b.a_id IS NULL;


0 commentaires