2017-09-29 1 views
0

J'essaie de concevoir une instruction SQL où j'obtiens ladite erreur dans le sujet. Je comprends qu'il y a d'autres sujets sur cette erreur mais je n'en ai vu aucun concernant mon problème spécifique où j'essaye d'obtenir une valeur basée sur plusieurs rangées. J'apprécierais n'importe quelle perspicacité. Voici mes tables et instructions SQL simplifiées.Problèmes avec SQL ERROR: sous-requête retourné plus de 1 ligne

TableA:

member_id 
---------- 
1 
2 
3 
4 

TableB:

user_id field_id value 
------------------------ 
1  1   red 
2  2   red 
1  2   blue 
4  1   red 
2  1   blue 
3  1   blue 

Requête:

SELECT DISTINCT(member_id) 
FROM TableA 
WHERE member_id = (SELECT b.user_id 
        FROM TableB b 
        INNER JOIN TableB a on a.user_id = b.user_id 
        WHERE a.field_id = '1' ANd a.value = 'red' 
        AND b.field_id = '2' ANd b.value = 'blue') 

Je suis en train de sélectionner le member_id du tableau A comme user_id dans le tableau B où, dans la table B, l'ID de champ de l'utilisateur (1) = rouge et l'ID de champ du même utilisateur (2) = bleu.

Par conséquent, l'instruction select doit retourner le member_id avec id = 1.

+0

Vous avez une erreur? Je pense que vous pourriez obtenir ce que vous voulez en mettant simplement distinct dans votre sous-requête et en effaçant la requête externe complètement –

Répondre

1

Utilisez la requête que vous aviez pour la sous select et juste JOIN tableA.

SELECT a.* 
FROM TableB b1 
INNER JOIN TableB b2 on b1.user_id = b2.user_id 
INNER JOIN tableA a ON a.member_id = b1.user_id 
WHERE b2.field_id = '1' ANd b2.value = 'red' 
    AND b1.field_id = '2' ANd b1.value = 'blue' 
0

Votre requête interne est en train de faire une jointure de TableB à lui-même. Ceci n'est presque jamais nécessaire.

Si vous voulez des enregistrements de tableA où le user_id = member_id et field_ID = 1 quand value = red ou field_id = 2 quand value = blue, vous aurez envie quelque chose de plus comme ceci:

SELECT distinct(member_id) 
FROM TableA inner join TableB on user_id = member_id 
WHERE (field_id = '1' AND value = 'red') 
    OR (field_id = '2' AND value = 'blue') 

Si vous voulez que les enregistrements où ils ont à la fois, juste jeter un distinct sur votre requête interne originale.

+0

Je pense que votre logique est défectueuse et la personne en effet besoin des deux jointures. S'il met AND, la condition (field_id = '1' et somethingelse) et (field_id = '2' et quelque chose d'autre) ne sera jamais vraie. –

+0

Bon point. Votre commentaire sur son message original est également correct. – TheAtomicOption

1

Groupement par user_id, vous pouvez essayer de compter les coups et filtrer en conséquence:

SELECT user_id 
    FROM tableB 
    GROUP BY user_id 
    HAVING SUM(CASE WHEN field_id = 1 AND value = 'red' THEN 1 ELSE 0 END) > 0 
    AND SUM(CASE WHEN field_id = 2 AND value = 'blue' THEN 1 ELSE 0 END) > 0 

Et que diriez-vous une autre variante:

SELECT * 
    FROM tableA AS a 
    WHERE EXISTS (SELECT 1 FROM tableB b where b.user_id = a.member_id AND B.field_id = 1 AND B.value = 'red') 
    AND EXISTS (SELECT 1 FROM tableB b where b.user_id = a.member_id AND B.field_id = 2 AND B.value = 'blue')