3

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

结果是正确的,我得到了我正在寻找的所有列。但我也得到了某种笛卡尔积,我得到了两条或更多条线,结果几乎相同。

我怎样才能避免这种情况?我希望每行只有一次,因为结果应该出现在网络搜索中。

更新

我首先尝试SELECT DISTINCT通过使用以下语句来确定这件事是否可行:pastie.org/970959但它仍然给了我一个笛卡尔积。这有什么问题?

4

5 回答 5

2

JOIN这是在什么条件下tables?你有foreign keys还是什么?

也许你应该在每张桌子上分别找到那个词?

于 2010-05-20T09:06:19.207 回答
2

试试SELECT DISTINCT

于 2010-05-20T09:05:13.067 回答
1

你使用什么样的服务器?Microsoft SQL Server 具有全文索引功能(我认为其他人也有类似的功能),它可以让您以更少资源密集型的方式搜索关键字。

还可以考虑使用 UNION 而不是加入表。

于 2010-05-20T09:07:16.487 回答
0

如果您的表是实体类型的表,例如a人员和b公司,那么如果您以这种方式搜索结果(单个查询),我认为您无法避免笛卡尔积。

您说要在所有表中搜索某个单词,但您可能希望将结果分成相应的类型。正确的?否则,网络搜索将没有多大意义。因此,如果您搜索“Joe”,您希望看到包含名称“Joe”的人,例如名为“Joe's gym”的公司。由于您正在搜索不同的实体,因此您应该将搜索拆分为不同的查询。

如果您真的想在一个查询中执行此操作,则必须更改数据库结构以适应。您将需要某种形式的“搜索表”,其中包含实体 ID (PK) 和实体类型,以及您希望找到该实体的关键字列表。例如:

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

类似的东西?

但是,当您的搜索仅返回一种类型的实体(例如人员)并且您想要返回您在该关键字上获得命中的人员(在与该人员相关的任何表中)时,情况就不同了。然后,您需要选择所有要显示的字段并按它们分组,而忽略您正在搜索的字段。包括它们不可避免地会导致笛卡尔积。

顺便说一句,我只是在这里集思广益。它希望它会有所帮助。

于 2010-05-20T09:16:46.500 回答
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 进行过滤。

于 2010-05-20T09:08:38.547 回答