2011-06-16 5 views
0

Dites que j'ai deux tables - "Table1" et "Table2" dans ma base de données MySQL. La clé primaire "id" (auto_increment) dans "Table1" est la clé de référence dans "Table2" - "tab_id".requête mysql join/sous-requête/union

Il peut y avoir zéro ou plusieurs lignes "Table2" pour une ligne "Table1".

Maintenant, j'essaie de faire une recherche sur l'une des colonnes dans "Table2" dire "email" colonne OU sur l'une des colonnes dans "Table1" dire "adresse" et imprimer "Table1" valeurs de ligne.

Je vois qu'il ya 3 possibilités: 1. 2. Sous Joignez-Query 3. Union

1 Se

SELECT * 
FROM Table1 t1, Table t2 
WHERE t1.id = t2.tab_id 
    AND (t1.address like '%str%' OR t2.email like '%str%'); 

- Cela fonctionne très bien, mais quand il n'y a pas de lignes dans "Table2" correspondant à "Table1" .. le JOIN va échouer, donc la sortie est in-consistante.

2 Sous-Query

SELECT * 
FROM Table1 t1 
WHERE t1.address like '%str%' 
    OR t1.id IN (SELECT t2.tab_id 
       FROM Table2 t2 
       WHERE t2.email like '%str%'); 

- Cela fonctionne très bien, mais quand il y a deux rangées Manys dans "Tableau 2" (disons 5 km) la requête va très lent :(

3 Union

SELECT 'relevant_columns' 
FROM Table1 t1, Table t2 
WHERE t1.id = t2.tab_id 
    AND (t1.address like '%str%' OR t2.email like '%str%') 
UNION 
SELECT 'relevant_columns' 
FROM Table1 t1 
WHERE t1.address like '%str%' 
ORDER BY relevant_column 

- Cela fonctionne très bien, peut-être créer une vue avec une UNION similaire, fait le travail

N. ow, ma question quelle est la bonne façon ... est-il correct d'appeler UNION toujours?

Engine MySQL: MyISAM

+0

Vous ne savez pas exactement ce que vous essayez de faire, mais cela ressemble à un travail pour une jointure externe, par opposition à une union. Peut-être regarder dans ça? – MJB

Répondre

1
SELECT * 
FROM Table1 t1 
    LEFT JOIN Table2 t2 
     ON t1.id = t2.tab_id 
WHERE t1.address like '%str%' OR t2.email like '%str%'; 
2
SELECT * 
    FROM Table1 t1 
    LEFT JOIN Table t2 ON t2.tab_id = t1.id 
WHERE t1.address like '%str%' 
    OR t2.email like '%str%'; 
  1. Vous devez faire un LEFT JOIN. Lorsque vous créez un FROM à partir de deux tables comme vous l'avez fait, cela fonctionne comme INNER JOIN (ou une CROSS JOIN s'il n'y a pas de clause WHERE), ce qui signifie que la sortie affiche uniquement les lignes qui correspondent dans les deux tables. Avec LEFT JOIN vous avez dit que vous voulez toutes les lignes de la table de gauche (t1) avec la ligne correspondante sur la table de droite (t2). S'il n'y a pas de correspondance en t2, alors null est utilisé.

  2. Vous pouvez utiliser la sous-requête, mais comme vous pouvez le voir est pas le meilleur choix

  3. Un UNION ici ne vous donne aucun avantage. Un UNION est utile pour fusionner des ensembles de données avec les mêmes colonnes.

Modifier

Si vous avez des problèmes avec JOIN, parce que certaines lignes ne semblent pas Table1, alors vous avez besoin d'un LEFT JOIN. Le fait qui prend beaucoup de temps est un autre problème. Ces tables ne sont pas grandes du tout, donc je suppose que vous devez faire un travail d'indexation sur ces tables.

Si vous voulez de l'aide sur le union vous devez me dire quels sont ces relevant_columns, car ils doivent avoir le même nombre de colonnes, le même type et la même séquence. Vous pouvez optimiser le union sans jointures, en fonction de ce que vous voulez sortir lorsque t2.email a une correspondance. Voici un exemple

SELECT t1.id, t1.address, null as email 
    FROM Table1 t1 
WHERE t1.address like '%str%' 
union 
SELECT t2.tab_id as id, null as address, t2.email 
    FROM Table t2 
WHERE t2.email like '%str%'; 
+0

Merci pour la réponse. Mais le LEFT JOIN prend environ 13 secondes par rapport à un simple (comme je l'ai écrit) qui prend 0.13 secondes, encore une fois les problèmes le simple JOIN fonctionne seulement lorsque "Table2" a une ou plusieurs références, UNION prend environ 0.16 secondes. "Table1" a 2600 lignes, et "Table2" a environ 3000 lignes – user237865

+0

@ user237865 –