2011-09-05 6 views
1

Table EmplacementsComment utiliser rejoindre correctement

loc_id loc_name  hier2 hier3 hier4 hier5 hier6 hier7 hier8 hier9 
152675 Castelli  105  109  0  319  14356 152673 152675 0 
14356 Rome   105  109  0  319  14356 0  0  0  
... 

Tableau Lacations Références

oid  name  loc_id 
12  Demo Villa 152675 
... 

Maintenant, je tente de trouver des entrées utilisateur effectue une recherche en entrant la chaîne "caste":

SELECT geo.loc_id, geo.loc_name AS name 
FROM locations AS geo 
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id 
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id 
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id  
WHERE geo.loc_name LIKE 'caste%' 
GROUP BY geo.loc_name 

Cela fonctionne. Je reçois l'entrée avec LOC_ID 152675

Maintenant, je veux seulement obtenir ces entrys que nous avons des objets dans Donc, je rejoins la table de référence.

SELECT geo.loc_id, geo.loc_name AS name 
FROM locations AS geo 
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id 
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id 
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id 
RIGHT JOIN locations_xref AS gx ON geo.loc_id = gx.loc_id 
WHERE geo.loc_name LIKE 'caste%' 
GROUP BY geo.loc_name 

Cela fonctionne. Encore une fois j'obtiens l'entrée de localisation avec loc_id 152675 parce qu'il y a une référence.

PROBLÈME

Maintenant, les recherches des utilisateurs pour "Rome". Je ne reçois aucune entrée car il n'y a pas de référence d'objet directement à la ville "Rome". L'objet existant est référencé à un quartier de Rome.

Comme vous pouvez voir les entrées de district et de ville ont des ID de hiérarchie qui peuvent être utilisés pour identifier la structure correcte. Je ne peux pas l'obtenir pour travailler avec la table de référence, donc je reçois seulement les objets qui sont dans "Rome" ou dans un quartier qui fait partie de Rome.

Toute aide est grandement appréciée!

+0

Désolé, c'est une question idiote, mais pourquoi 'name' dans le tableau des références de localisation est différent de' loc_name' dans 'Locations' pour le même' loc_id'? Sont-ils censés être identiques ou est-ce normal qu'ils soient différents? Fondamentalement, je ne suis pas sûr de comprendre à quoi sert la table de références. –

+0

Le champ "nom" dans la table de référence fait référence au nom d'un objet immobilier. Cela n'a donc rien à voir avec les emplacements géographiques. – Mike

+0

Les colonnes 'hier2' ...' hier9' suggèrent une forme de table dés-normalisée sous-optimale qui rend vos requêtes complexes et lentes. –

Répondre

1

Je ne sais pas beaucoup sur vos données, mais de la première vue, il semble que hier6 a des informations sur la relation entre Rome et Castelli. Ainsi, la requête dont vous avez besoin peut sembler quelque chose de plus ou moins comme ceci:

SELECT geo.loc_id, geo.loc_name AS name 
FROM locations AS geo 
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id 
LEFT JOIN locations AS geoh6 ON geo.hier6 = geoh6.loc_id 
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id 
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id 
RIGHT JOIN locations_xref AS gx ON geo.loc_id = gx.loc_id 
WHERE geoh6.loc_name LIKE 'rome%' 
GROUP BY geo.loc_name 
+0

Utile pour souligner le PO comment fonctionne sa propre hiérarchie. Je ne pense pas que cela lui donnera ce qu'il veut, mais c'est certainement un pas dans la bonne direction. –

+0

C'est ce que j'avais déjà, mais ça n'a pas marché pour moi. Nous avons trouvé une autre solution aujourd'hui en divisant la requête en deux parties. C'est aussi rapide. Merci quand même. – Mike

1

Vous pouvez modifier votre requête (comme Karolis suggéré), mais je ne pense pas que cela vous donnera ce que vous voulez. Votre requête retournera "Castelli" lorsque vous recherchez "Rome%", mais elle ne renverra pas "Rome". Il ne retournera pas 'Rome', parce que 'Rome' n'est pas dans votre table xréf. Pour renvoyer 'Rome' avec ce type de requête, vous devez insérer une ligne pour 'Rome' dans la table xréf.

Vous pouvez obtenir toutes les choses qui sont "dans" Rome avec UNION, mais il ne référence pas du tout votre table xréf.

select la.loc_id, la.loc_name 
from locations la 
where la.loc_name like 'Rome%' 
union 
select lb.loc_id, lb.loc_name 
from locations lb 
inner join locations lc on lc.hier6 = lb.hier6 

Il n'est pas clair pour moi comment vous déterminez quelle colonne utiliser pour la jointure au moment de l'exécution.

Plus tard. . .

Si vous ne connaissez pas les colonnes à utiliser au moment de l'exécution, vous devez les quitter. Et comme vous ne savez pas si la chaîne de recherche peut faire référence à une valeur jointe via la colonne hier2, hier3, hier4, etc., vous devez également vérifier chacune de ces colonnes pour une correspondance.

Si locations_xref se comporte comme un filtre, vous avez besoin d'une jointure interne sur cette table, ainsi que d'une ligne pour 'Rome'.(Parce que vous avez des propriétés à Rome.) Probablement quelque chose dans ce sens.

SELECT geo.loc_id, geo.loc_name AS name 
FROM locations AS geo 
LEFT JOIN locations AS geoh2 ON geo.hier2 = geoh2.loc_id 
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id 
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id 
LEFT JOIN locations AS geoh5 ON geo.hier5 = geoh5.loc_id 
LEFT JOIN locations AS geoh6 ON geo.hier6 = geoh6.loc_id 
LEFT JOIN locations AS geoh7 ON geo.hier7 = geoh7.loc_id 
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id 
LEFT JOIN locations AS geoh9 ON geo.hier9 = geoh9.loc_id 
INNER JOIN locations_xref lx on lx.loc_id = geo.loc_id 
WHERE geo.loc_name LIKE 'Rom%' 
    or geoh2.loc_name like 'Rom%' 
    or geoh3.loc_name like 'Rom%' 
    or geoh4.loc_name like 'Rom%' 
    or geoh5.loc_name like 'Rom%' 
    or geoh6.loc_name like 'Rom%' 
    or geoh7.loc_name like 'Rom%' 
    or geoh8.loc_name like 'Rom%' 
    or geoh9.loc_name like 'Rom%' 

Avant de trop investi dans ce modèle, vous devriez jeter un oeil à Bill Karwin's database antipatterns. "Naive Trees" commence sur la diapositive 48.

+0

Chaque colonne "hierX" fait référence à une hiérarchie géographique plus profonde. Donc, si quelqu'un cherche "Rome", chaque colonne de la hiérarchie devrait être recherchée, parce qu'il y a une ville appelée "Rome" et peut-être un petit endroit appelé "Romena". Votre droit de ne pas retourner "Rome" lors de la recherche de "Rome". Je ne comprends pas votre réponse. Pourriez-vous l'expliquer mieux s'il vous plaît? – Mike

+0

Un "Pizzaria" ne sera pas retourné, parce que les emplacements contiennent seulement des emplacements géographiques comme des villes, des secteurs, des régions aussi. – Mike

+0

Une requête comme celle que j'avais déjà. La question était comment puis-je exclure les emplacements qui ne contiennent aucun objet. Je l'ai essayé avec 'DROIT JOIN emplacements_xref AS gx ON geo.loc_id = gx.loc_id' – Mike