使用OR进行SELECT,包括表连接

时间:2008-11-21 19:41:49

标签: sql

我有一个包含三个表的数据库:书籍(书籍详细信息,PK是CopyID),关键词(关键词列表,PK是ID)和KeywordsLink这是书籍和关键词之间的多个链接表字段ID,BookID和KeywordID。

我正在尝试在我的应用中创建一个高级搜索表单,您可以在其中搜索各种条件。目前我已经与Title,Author和Publisher合作(全部来自Book表)。它产生SQL,如:

SELECT * FROM Books WHERE Title Like '%Software%' OR Author LIKE '%Spolsky%';

我想将此搜索扩展为使用标记进行搜索 - 基本上是添加另一个OR子句来搜索标记。我试过这样做

SELECT *
    FROM Books, Keywords, Keywordslink
    WHERE Title LIKE '%Joel%'
       OR (Name LIKE '%good%' AND BookID=Books.CopyID AND KeywordID=Keywords.ID)

我认为使用括号可能会将第二部分分成它自己的kinda子句,因此仅在该部分中评估连接 - 但它似乎并非如此。它给我的全部是一本书的多个副本的长列表,满足Title LIKE '%Joel%'位。

有没有办法使用纯SQL执行此操作,或者我是否必须使用两个SQL语句并将它们组合在我的应用程序中(在此过程中删除重复项)。

我现在正在使用MySQL,如果这很重要,但该应用程序使用ODBC,我希望使它与数据库无关(甚至可能最终使用SQLite或拥有它,以便用户可以选择使用哪个数据库)。

7 个答案:

答案 0 :(得分:7)

您需要将3个表连接在一起,这为您提供了一个表格结果集。然后,您可以检查您喜欢的任何列,并确保获得不同的结果(即没有重复项)。

像这样:

select distinct b.*
from books b
left join keywordslink kl on kl.bookid = b.bookid
left join keywords k on kl.keywordid = k.keywordid
where b.title like '%assd%'
or k.keyword like '%asdsad%'

您还应该尝试避免使用百分号(%)启动LIKE值,因为这意味着SQL Server无法在该列上使用索引并且必须执行完整(和慢速)表扫描。这开始使您的查询成为“开始于”查询。

也许考虑SQL Server中的全文搜索选项。

答案 1 :(得分:3)

您在此处所做的是通过将表格与逗号连接但没有任何连接条件来设置笛卡尔结果集。切换语句以使用外连接语句,这应该允许您引用关键字。我不知道你的架构,但也许这样的东西会起作用:

SELECT 
  * 
FROM 
  Books 
  LEFT OUTER JOIN KeywordsLink ON KeywordsLink.BookID = Books.CopyID 
  LEFT OUTER JOIN Keywords ON Keywords.ID = KeywordsLink.KeywordID 
WHERE Books.Title LIKE '%JOEL%' 
      OR Keywords.Name LIKE '%GOOD%'

答案 2 :(得分:3)

使用UNION

(SELECT Books.* FROM <first kind of search>)
UNION
(SELECT Books.* FROM <second kind of search>)

关键是你可以写两个(或更多)简单而有效的查询,而不是一次尝试做所有事情的复杂查询。

如果结果行的数量很少,那么UNION的开销就会很小(如果你没有重复或者不关心它们,你可以使用更快的UNION ALL。)< / p>

答案 3 :(得分:1)

SELECT * FROM books WHERE title LIKE'%Joel%' OR bookid IN 
         (SELECT bookid FROM keywordslink WHERE keywordid IN
         (SELECT id FROM keywords WHERE name LIKE '%good%'))

请注意旧版本的MySQL不喜欢子选择。我认为他们已经解决了这个问题。

答案 4 :(得分:0)

您还必须通过指定

之类的内容来限制联接的产品
Books.FK1 = Keywords.FK1 and
Books.FK2 = Keywordslink.FK2 and
Keywords.FK3 = Keywordslink.FK3

但我不知道您的确切数据模型,因此您的解决方案可能略有不同。

答案 5 :(得分:0)

我不知道在SQL中实现“条件连接”的任何方法。我认为你最好分别执行两个语句并将它们组合在应用程序中。这种方法也更可能与数据库无关。

答案 6 :(得分:0)

看起来Neil Barnwell已经涵盖了我会给出的答案,但我会添加一件事......

书籍可以有多个作者。如果您的数据模型确实是按照查询暗示的那样设计的,那么您可能需要考虑更改它以适应这一事实。