表格位置
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,可用于标识正确的结构。我只是不能让它与参考表一起工作,所以我只得到那些在“罗马”或区域内的对象,这是罗马的一部分。
非常感谢任何帮助!
答案 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开始。