用于具有多个表连接的搜索查询的SQL

时间:2017-06-12 12:20:51

标签: php sql join

我有以下表格

  

文档

     
      
  • docid(PK)
  •   
  • URL
  •   
     

WDATA

     
      
  • wordid(PK)
  •   
  •   
     

wtitle

     
      
  • 的wordID
  •   
  • 的docID
  •   
     

(wordid& docid结合独特)

     

wurl

     
      
  • 的wordID
  •   
  • 的docID
  •   
     

(wordid& docid结合独特)

为了搜索任何短语,我将其分解为单词并获取其wordid。表wtitlewurl将用于评分排名的行。我打算添加更多的表来进行评分,如inlink,inh1标签等。但是我有问题框架我的搜索单词的SQL查询。

我的SQL查询就像

SELECT d.docid,furl,IF(t.wordid IS NULL,0,1) AS intitle,IF(u.wordid IS NULL,0,1) AS inurl FROM document d
LEFT JOIN wtitle t ON t.docid=d.docid
LEFT JOIN wdata w ON w.wordid=t.wordid
LEFT JOIN wurl u ON u.wordid=w.wordid AND u.docid=d.docid
WHERE w.wordid IN (wordid1,wordid2,wordid3)

我有以下怀疑

  1. 如何检查每个表格wtitlewurl两个甚至更多,因为目前在wtitle中搜索第一个因为LEFT JOIN而忽略了其他联接?
  2. 如何正确构建此SQL查询?

    SQL FIddle http://sqlfiddle.com/#!9/ab0052/4/0

  3. Wordid 3在网址中,但不在Docid 2的标题中

    Wordid 3不在网址中,而是在Docid 3的标题中

    我想要返回doc 2和3,但是因为它首先通过wtitle加入它忽略(使用第一个查询数据)其他连接

1 个答案:

答案 0 :(得分:1)

如果您想知道,例如,您要查找的两个单词是否在文档中出现两个,则必须查看标题和网址的组合。 (否则,如果您知道标题中存在其中一个单词,并且在网址中存在一个单词,则您不会知道它是相同的单词还是两个单词。)因此,将这两个表与{{1}组合首先,但要记住哪条记录属于哪个表。然后我们可以计算合并和每个地方(标题或网址)。

这是一个查找单词ID 3和4的查询。它列出了首先匹配两个单词的条目,然后是只有一个单词匹配的文档:

IQueryable

您可以通过替换

来查找单词而不是单词ID
Contains

通过

UNION ALL

Rextester链接:http://rextester.com/KPVX67861(SQL小提琴在大多数情况下对我都不起作用。)

我建议这些覆盖索引:

SELECT 
  d.docid, 
  d.furl, 
  w.cnt_combined,
  w.cnt_in_title,
  w.cnt_in_url
FROM document d
JOIN
(
  select
    docid,
    count(distinct wordid) cnt_combined,
    sum(place = 'TITLE') cnt_in_title,
    sum(place = 'URL') cnt_in_url
  from
  (
    select 'TITLE' as place, docid, wordid from wtitle where wordid in (3,4)
    union all
    select 'URL' as place, docid, wordid from wurl where wordid in (3,4)
  ) both_tables
  group by docid
) w ON w.docid = d.docid
order by w.cnt_combined desc;

首先使用where wordid in (3,4) ,DBMS可以轻松找到条目,并且由于where wordid in (select wordid from wdata where word in ('vaccination', 'the')) 已经在索引中,因此DBMS不必访问该表。它从索引中获取所有数据。 (这就是为什么它们被称为覆盖索引;它们涵盖了查询所需的所有列。)