2016-02-01 1 views
0

Je vais essayer d'expliquer mon problème. J'ai deux tables. Dans le premier, chaque enregistrement est identifié par un code INT unique (compteur). Dans la seconde, le code de la première table est l'un des champs (et peut être répété dans divers enregistrements).MySQL Sélectionnez le jeu d'enregistrements WHERE IN

Je veux faire un SELECT CODE dans la deuxième table, sur la base WHERE paramètres, sachant que je vais obtenir comme résultat un jeu d'enregistrements avec éventuellement répétée CODES, et utiliser ce jeu d'enregistrements pour un autre SELECT dans la première table, WHERE CODE IN le jeu d'enregistrements ci-dessus (de la deuxième table).

Est-ce possible? Et si oui, comment faire cela?

Habituellement, si j'utilise la clause WHERE IN, le tableau peut contenir des valeurs répétées comme WHERE code IN "3,4,5,6,3,4,2" ... non? La différence ici est que je veux utiliser un jeu d'enregistrements précédemment sélectionné à la place du tableau.

+0

en savoir plus sur Joins.http: //blog.codinghorror.com/a-visual-explanation-of-sql-joins/; Comprendre également la cardinalité. Ce que vous avez est une relation de un à plusieurs A -> où A.Code = B.A_CODE et B.A_Code peuvent être répétés (ainsi est la nature d'une clé étrangère) Il semble que vous ne vouliez afficher que les valeurs de A Table Vous pouvez le faire en utilisant une sous-requête exists et une sous-requête coorlated ou vous pouvez utiliser une jointure externe et un groupe by ou distinct. – xQbert

Répondre

0

Est-ce possible? Bien sûr.

Et si oui, comment faire? Comme la plupart des questions, les réponses dépendent. Il y a plus d'une façon de peler ce chat; et en fonction des données (volume d'enregistrements), et les réponses peuvent varier.

Vous pouvez utiliser un séparateur ou un groupe pour limiter les enregistrements de la table A car la jointure de A -> b est un 1 -> beaucoup, donc nous devons les distinguer ou les grouper par les valeurs de A comme ils le seraient répété. Mais si vous avez aussi besoin de valeurs de B, c'est la façon de le faire.

Select A.Code, max(count B.A_CODE) countOfBRecords 
from B 
LEFT JOIN A 
on A.Code = B.A_Code 
WHERE B.Paramater = 'value' 
and B.Paramater2 = 'Value2' 
group by A.Code) 

ou en utilisant votre approche (fonctionne que si vous avez besoin uniquement des valeurs/colonnes du tableau A.)

Select A.Code 
from A 
Where code in (Select B.A_CODE 
       From B WHERE B.Paramater = 'value' 
       and B.Paramater2 = 'Value2') 

Mais ceux-ci peuvent être lent en fonction de données/index.

Vous n'avez pas besoin de la requête distincte dans la requête interne car A.Code n'existe qu'une seule fois et ne sera donc pas répété. C'est le JOIN qui ferait que les enregistrements ne répètent pas la clause where.

-Correlated sous-requête retournera un seul A.Code fonctionne si vous avez besoin que les valeurs de la table A.

Select A.Code 
From A 
Where exists (Select 1 
       from B 
       where b.paramter = value ... 
       AND A.Code = B.A_CODE) 

Comme il n'y a pas de jonction pas A.records serait répété. Sur les ensembles de données plus volumineux, cela fonctionne généralement mieux.

Cette dernière approche fonctionne car elle corrèle la table externe avec le sous-select Notez que cela ne peut aller que d'un niveau dans une relation. Si vous aviez plusieurs niveaux en essayant de rejoindre cette voie, cela ne marcherait pas.

+0

Tout d'abord ... merci beaucoup !! La dernière solution semble la meilleure pour mon cas, selon ce que vous avez décrit (j'ai juste besoin des valeurs du champ dans une table et ira juste à un niveau profond dans l'imbrication). J'ai juste une question ... dans la sous-requête que vous avez écrite SELECT 1 FROM B ... qu'est-ce que ce "1" signifie/représente? – Lawrence

+0

une autre sous-question ...puis-je écrire quelque chose comme: sélectionnez un.code d'un où existe (sélectionnez 1 de B où ....) ET existe (sélectionnez 1 de C où ....) ??? – Lawrence

+0

... juste pour vous faire une idée, ces tables ont quelques dizaines de milliers d'enregistrements de taille moyenne. – Lawrence