2017-06-12 78 views
0

我有如下表SQL與多個表的搜索查詢加入

文件

  • 文檔ID(PK)
  • 網址

WDATA

  • 的wordID(PK)

wtitle

  • 的wordID
  • 的docID

(的wordID &文檔ID組合是唯一的)

wurl

  • 的wordID
  • 文檔ID

(wordID的&文檔ID組合是唯一的)

搜索我打破它到任何文字短語,並得到其wordid 。表格wtitle,wurl將被用於排名評分。我打算添加更多的表格,如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搜索第一個JOIN和其他連接被忽略?
  2. 如何正確構建此SQL查詢?

    SQL小提琴http://sqlfiddle.com/#!9/ab0052/4/0

的wordID 3是URL,但不是在DOCID的標題2

的wordID 3是不是在URL,但在DOCID 3的標題

我要回然而,doc 2和3都是因爲它首先通過wtitle加入它忽略了(使用第一個查詢數據)其他連接

+0

什麼可以幫助您創建一些簡短的測試數據併爲自己進行驗證。看看你是否可以得到值來匹配。 –

+1

請注意,'LEFT JOIN w ... WHERE w = ...'與'INNER JOIN w'相同' – Strawberry

+0

如需進一步幫助,請參閱:[爲什麼我應該爲我看來的MCVE一個非常簡單的SQL查詢?](https://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-bea-a-非常簡單的sql查詢) – Strawberry

回答

1

如果您想知道是否說兩個字你重新尋找這兩個在一個文件中,你必須看看標題和網址合併。 (否則,如果您知道其中一個詞出現在標題中,並且一個詞存在於url中,則不知道它是同一個詞還是兩個詞。)因此,首先將兩個表與UNION ALL結合起來,但請記住哪個記錄屬於哪個表。然後我們可以統計每個地點(標題或網址)。

下面是一個查詢,查找單詞ID 3和4。它列出了只匹配一個關鍵詞匹配兩個詞在前​​,後跟文件中的條目:

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 (select wordid from wdata where word in ('vaccination', 'the')) 

Rextester鏈接替換

where wordid in (3,4) 

詞ID:http://rextester.com/KPVX67861(SQL撥弄不爲我的大部分時間工作。)

我建議這些覆蓋索引:

CREATE INDEX idx_wtitle ON wtitle(wordid, docid); 
CREATE INDEX idx_wurl ON wurl(wordid, docid); 

隨着wordid第一DBMS可以很容易地找到這些條目,並作爲docid已經在索引,DBMS不必訪問表。它從索引獲取所有數據。 (這就是爲什麼它們被稱爲覆蓋索引的原因;它們涵蓋了查詢所需的所有列。)

+0

哇非常感謝,我真的很喜歡這個'place'的別名的想法,並添加總和,它當然給了我一些想法,但是你的SQL查詢並沒有正確使用索引,對於我在'wdata'表和大'wdoc'表中有1000萬個數據的情況,執行這個搜索查詢需要幾分鐘的時間。 既然您正在使用'UNION',我將內部條件轉移到了更好的性能!更接近我想要的東西!也許我可以用多個積分表來完成聯盟,並總結得分或數!謝謝你的幫助 ! –

+1

是的,移動WHERE子句並將其直接應用到表中是個不錯的主意。 (我習慣了甲骨文,它的優秀的優化器在內部完成了這個工作,所以我不必兩次編寫相同的條件。似乎我有點被寵壞了;-)我推薦使用以下兩個索引來運行儘可能快:'wtitle(wordid,docid)'和'wurl(wordid,docid)'。在這些索引中首先使用'wordid'是很重要的,所以可以很快找到它們。 DBMS甚至不必讀取表格,因爲它直接從索引中獲得'docid'。 –