我有6张桌子,我们称之为a,b,c,d,e,f。现在我想搜索某个单词的所有表的所有列(ID列除外),让我们说'Joe'。我做的是,我在所有表上进行了INNER JOINS,然后使用LIKE搜索列。
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。但是我也得到了某种笛卡尔积,我得到2行或更多行几乎相同的结果。
我该如何避免这种情况?我想要每行只有一次,因为结果应该出现在网络搜索中。
更新
我首先尝试通过使用此声明来确定SELECT DISTINCT
是否有效:pastie.org/970959但它仍然给我一个笛卡尔积。这有什么问题?
答案 0 :(得分:2)
试试SELECT DISTINCT
?
答案 1 :(得分:2)
你在JOIN
这个tables
的条件是什么?你有foreign keys
还是什么?
也许你应该分别在每张桌子上找到这个词?
答案 2 :(得分:1)
您使用的是哪种服务器? Microsoft SQL Server具有全文索引功能(我认为其他人也有这样的功能),它允许您以更少资源密集的方式搜索关键字。
另外考虑使用UNION而不是连接表。
答案 3 :(得分: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进行过滤。
答案 4 :(得分:0)
如果您的表是实体类型表,例如a
是个人而b
是公司,我认为如果您搜索,则不能避免使用笛卡尔积以这种方式得到结果(单一查询)。
您说要在所有表中搜索某个单词,但您可能希望将结果分成相应的类型。对?否则,网络搜索没有多大意义。 因此,如果您搜索“Joe”,您希望看到名为“Joe”的人,例如名为“Joe's gym”的公司。由于您要搜索不同的实体,因此应将搜索拆分为不同的查询。
如果您确实想在一个查询中执行此操作,则必须更改数据库结构以适应。您将需要某种形式的“搜索表”,其中包含实体ID(PK)和实体类型,以及您希望找到该实体的关键字列表。例如:
EntityType, EntityID, Keywords
------------------------------
Person, 4, 'Joe', 'Doe'
Company, 12, 'Joe''s Gym', 'Gym'
那样的东西?
然而当您的搜索只返回一种类型的实体(比如一个Person)时,它会有所不同,并且您希望返回对该关键字有效的人(在任何相关的表中)人)。然后,您需要选择要显示的所有字段并按其分组,而不显示您要搜索的字段。包括它们不可避免地导致笛卡尔积。
顺便说一句,我只是在这里集思广益。希望它有所帮助。