2010-05-20 376 views
3

我有6個表,我們稱它們爲a,b,c,d,e,f。現在,我想搜索某個單詞的所有表的列(除了ID列),讓我們說'喬'。我所做的是,我在所有表格上做了INNER JOINS,然後使用LIKE來搜索列。如何在INNER JOIN查詢中避免笛卡爾積?

INNER JOIN 
... 
ON 
INNER JOIN 
... 
ON.......etc. 
WHERE a.firstname 
~* 'Joe' 
OR a.lastname 
~* 'Joe' 
OR b.favorite_food 
~* 'Joe' 
OR c.job 
~* 'Joe'.......etc. 

結果是正確的,我得到所有我想找的colums。但我也得到了一些笛卡爾產品,我得到了兩條或更多條線,結果幾乎相同。

我該如何避免這種情況?我希望每行只有一行,因爲結果應該顯示在網頁搜索上。

UPDATE

我第一次嘗試弄清楚如果SELECT DISTINCT事情會使用下面的語句工作:pastie.org/970959但它仍然給了我一個笛卡爾乘積。這有什麼問題?

+0

請指定你使用的數據庫。 – hgulyan 2010-05-20 09:08:15

回答

2

嘗試SELECT DISTINCT

+0

即使它是SQL Server? – hgulyan 2010-05-20 09:09:18

+1

MS SQL服務器仍然有選擇不同,不是嗎? – oedo 2010-05-20 09:10:45

+0

感謝您的提示。 – flhe 2010-05-20 09:13:58

2

你在什麼條件下JOIN這個tables?你有foreign keys什麼的?

也許你應該在每張桌子上分別找到這個詞?

+0

我有表格之間的關係,所以我做INNER JOIN到person_has_job表格並從那裏到作業表格。 – flhe 2010-05-20 09:17:14

1

你在使用什麼樣的服務器? Microsoft SQL Server具有全文索引功能(我認爲其他人也有類似的內容),這使您可以用資源密集型的方式搜索關鍵字。

另外考慮使用UNION而不是加入表。

+0

這是一個postgresql服務器。 – flhe 2010-05-20 09:12:44

0

沒有看到你的表格,我只能真的假設這裏發生了什麼是你有一個一對多的關係。您可能想要在子查詢中執行所有操作,選擇不同的ID,然後根據ID獲取要顯示的數據。喜歡的東西:

SELECT a.*, b.* 
FROM (SELECT DISTINCT a.ID 
     FROM ... 
     INNER JOIN ... 
     INNER JOIN ... 
     WHERE ...) x 
INNER JOIN a ON x.ID = a.ID 
INNER JOIN b ON x.ID = b.ID 

一對夫婦的事情,但是請注意,:

  • 這將是sloooow,你可能想使用全文搜索,而不是(如果您的RDBMS支持它)。

  • 單獨搜索每個表可能會更快,而不是先將所有內容都加入到笛卡爾積中,然後再使用OR進行過濾。

+0

這可能是解決方案,我會嘗試。謝謝! – flhe 2010-05-20 09:13:13

+0

好的,我會看看postgresql全文搜索。 – flhe 2010-05-20 09:20:38

+0

我第一次嘗試弄清楚SELECT DISTINCT是否可以通過使用下面的語句: http://pastie.org/970959 但它仍然給我一個笛卡兒的產品。這有什麼問題? – flhe 2010-05-21 11:44:51

0

如果您表是實體類型表,例如a是個人和b是公司,我不認爲你能避免笛卡爾乘積,如果你搜索這樣的結果(單查詢)。

你說你想搜索某個單詞的所有表格,但是你可能想把結果分成相應的類型。對?否則,網絡搜索沒有多大意義。 因此,如果您搜索'Joe',您希望看到包含名字'Joe'的人員和例如名爲'Joe's gym'的公司。由於您正在搜索不同的實體,所以您應該將搜索分解爲不同的查詢。

如果你真的想在一個查詢中做到這一點,你將不得不改變你的數據庫結構來適應。您需要一些包含實體ID(PK)和實體類型的「搜索表」,以及您希望找到該實體的關鍵字列表。例如:

EntityType, EntityID, Keywords 
------------------------------ 
Person,  4,  'Joe', 'Doe' 
Company, 12,  'Joe''s Gym', 'Gym' 

這樣的事情?

然而這是不同的,當你的搜索只返回一個類型的實體,說一個人,和你想返回,你得到(該人的任何相關表格)該關鍵字進行打擊的人。然後,您需要選擇所有要顯示的字段並按它們進行分組,而忽略正在搜索的字段。包括它們不可避免地導致笛卡爾產品。

順便說一句,我只是在這裏集思廣益。它希望它有幫助。