2011-09-05 65 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