2011-09-05 67 views
1

表位置如何使用权正确加入

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  
... 

表Lacations参考

oid  name  loc_id 
12  Demo Villa 152675 
... 

现在我试着输入字符串“种姓”找一些条目的用户搜索:

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 

This works。我得到loc_id 152675

现在我只希望得到那些我们在对象entrys项所以我加入了参考表:

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 

这工作。我再次使用loc_id 152675获取位置条目,因为它们是参考。

问题

现在的 “罗马” 的用户搜索。我没有得到任何条目,因为没有对象直接参考城市“罗马”。现有的对象被引用到罗马的一个区域。

正如您所看到的,分区和城市条目具有层次结构ID,可用于识别正确的结构。我只是不能将它与参考表一起使用,所以我只能得到那些位于“罗马”或罗马一部分区域的物体。

任何帮助,非常感谢!

+0

对不起,如果这是一个愚蠢的问题,但为什么同样的'loc_id'中Location Location表中的'name'与Locations中的'loc_name'不同?他们实际上应该是相同的还是完全正确的,他们是不同的?基本上,我只是不确定我了解参考表的用途。 –

+0

参考表中的“名称”字段是指房地产对象的名称。所以它与地理位置无关。 – Mike

+0

'hier2''' hier9'列提出了一个次优解规格化的表格,使您的查询变得复杂和缓慢。 –

回答

1

我不知道很多关于你的数据,但来自乍一看似乎hier6有大约罗马卡斯泰利之间关系的信息。因此,你需要查询可能看起来或多或少是这样的:

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

用于指出OP如何自己的层次结构。我不认为这会给他他想要的东西,但这绝对是朝着正确方向迈出的一步。 –

+0

这就是我已经有,但它没有为我工作。今天发现了另一个解决方案,将查询分成两部分。它也更快。不管怎么说,还是要谢谢你。 – Mike

1

你可以调整你的查询(如Karolis建议),但我不认为这会给你想要的东西。当您搜索'Rome%'时,您的查询将返回'Castelli',但它不会返回'Rome'。它不会返回'罗马',因为'罗马'不在你的外部参照表中。

要用这种查询返回“罗马”,您需要在'外部参照表'中插入一行'罗马'。

你可以通过一个UNION获得所有在罗马“in”的东西,但它根本不参考你的xref表。

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 

我不清楚在运行时如何确定在连接中使用哪个列。

后来。 。 。

如果您不知道在运行时要使用哪些列,则必须在所有列上进行LEFT JOIN。由于您不知道搜索字符串是否可能引用通过列hier2,hier3,hier4等连接的值,因此您还必须检查每个列以进行匹配。

如果locations_xref的行为类似于过滤器,那么您需要在该表上连接一个“罗马”的内部连接。(因为你在罗马有物业。)可能是沿着这些路线的东西。

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%' 

在你投入这个模型之前,你应该看看Bill Karwin's database antipatterns。 “天真的树”从幻灯片48开始。

+0

每个“hierX”列指的是更深的地理层次。因此,如果有人搜索“罗马”,应该搜索每个层级列,因为有一个名为“罗马”的城市,也可能是一个叫做“Romena”的小型城市。您在搜索“罗马”时不返回“罗马”的权利。我没有得到你的答案。你能解释一下吗? – Mike

+0

“Pizzaria”不会被退回,因为地点只包含城市,地区,地区等地理位置。 – Mike

+0

这样的查询我已经有了。问题是我如何排除不包含对象的位置。 我用'RIGHT JOIN locations_xref AS gx ON geo.loc_id = gx.loc_id'来试用它 – Mike