帮助Delphi 7,ADO和& MS Access SQL语句 - 部分Deuce

时间:2010-12-21 18:32:35

标签: sql delphi ms-access ado delphi-7

我需要帮助理解为什么我的SQL不起作用。或者,如果我需要以不同的方式编写它以获得我需要的结果。正如标题所示,我使用的是Delphi 7,ADO组件和MS Access 2000数据库。你可以在这里看到我的表格结构:
Help with Delphi 7, ADO, & MS Access SQL Statement

我目前用于获取基于关键字的所有知识的SQL如下:

select * from(知识K
内联系knowledge_keywords KKW on KKW.knowledgeid = K.id)
KW.id = KKW.keywordid上的内连接关键字KW where(KW.keyword ='job')AND(KW.keyword ='task')

但是,当knowledge_keywords表中显然具有相同知识id的那两个单词时,这不会返回并产生结果。

但是,如果我使用OR而不是AND执行相同的SQL,我会得到我预期的两条记录

select * from(知识K
内联系knowledge_keywords KKW on KKW.knowledgeid = K.id)
KW.id = KKW.keywordid上的内连接关键字KW where(KW.keyword ='job')AND(KW.keyword ='task')

感谢您的帮助

2 个答案:

答案 0 :(得分:5)

以这种方式思考:在knowledge_keywords中有多少记录是真实的两者关键字='作业' AND keyword ='task'。没有这样的记录。当您使用AND时,您要求的记录同时满足两者第一个条件和第二个条件。当您使用OR时,您要求的记录满足一个条件或另一个条件(或两者)。

在这种情况下,OR表达您想要的内容。并表达了不同的东西。

你也可以使用KW.keyword IN('job','task'),它更简洁,也许更清晰。

答案 1 :(得分:2)

我认为第一个查询不会返回任何结果,是吗?这是因为语音中的'和'与编程中的'和'不同。当你说,你想要关键字'job'和'task'时,你实际上意味着你想要关键字是'job''task'的行。关键字不能同时是“作业”和“任务”,因此查询不会返回任何行。您可以使用

形式的OR替换IN
WHERE KW.Keyword in ('job', 'task')

但这可能不会给你想要的结果。我怀疑你需要找到与这两个关键字相匹配的文章。 要检查知识库是否同时包含两个关键字,您可能需要这样的内容(尽管我不确定Access是否接受这个:

    select
      * 
    from 
      knowledge K
    where
      exists
          (select 'x' from
            knowledge_keywords KKW
            inner join keywords KW on KW.id = KKW.keywordid
          where
            KKW.knowledgeid = K.id and
             KW.keyword = 'job') 
      and exists
          (select 'x' from
            knowledge_keywords KKW
            inner join keywords KW on KW.id = KKW.keywordid
          where
            KKW.knowledgeid = K.id and
             KW.keyboard = 'task') and

[编辑]

一种不同的方法,可能在Access中效果更好(对不起,我无法测试)是使用这样的计数。对于这个例子,我对K中的字段做了一个小假设。 这样,您就可以加入列表中的每个关键字。对于同时具有“作业”和“任务”的知识库文章,它将首先返回两行。然后将这些行分组到知识字段中,并计算行数。仅返回count与匹配项总数匹配的文章。

可能的问题:当文章具有相同的关键字(作业)链接两次时,它仍然会被返回。这可以通过使用唯一约束来防止这种情况发生。

    select
      K.ID,
      K.Title,
      K.Content
    from
      knowledge K
      inner join knowledge_keywords KKW on KKW.knowledgeid = K.id)
      inner join keywords KW on KW.id = KKW.keywordid
    where 
      KW.keyword in ('job', 'task')
    group by
      K.ID,
      K.Title,
      K.Content
    having
      count(*) = 2 /* Number of keywords */