如何正确使用正确连接

时间:2011-09-05 12:52:00

标签: mysql sql

表格位置

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

表乳液参考文献

oid     name        loc_id
12      Demo Villa  152675
...

现在我尝试通过输入字符串“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

这很有效。我用loc_id 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  
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获取位置条目,因为它是一个引用。

问题

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

正如您所看到的,区和城市条目具有层次结构ID,可用于标识正确的结构。我只是不能让它与参考表一起工作,所以我只得到那些在“罗马”或区域内的对象,这是罗马的一部分。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

我对您的数据了解不多,但从第一眼看来hier6似乎有关于罗马 Castelli 之间关系的信息。因此,您需要的查询可能看起来或多或少像这样:

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

答案 1 :(得分:1)

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

要使用此类查询返回“Rome”,您需要在“外部参照”表中插入“罗马”行。

您可以使用UNION获取“在罗马”中的所有内容,但它根本不会引用您的外部参照表。

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开始。