2011-04-13 94 views
1

我試圖通過連續匹配的總數來訂購MySQL select語句。例如,如果表中的樣子......按命令匹配的MySQL順序

id | dessert | choice 
--------------------- 
1 | pie  | apple pie, chocolate pie 
2 | cake | chocolate cake, lemon cake, white chocolate cake, triple chocolate cake 
3 | donut | frosted donut, chocolate donut, chocolate cream donut 

...如果有人搜索chocolate,結果應該被下令:

dessert | matches 
----------------- 
cake | 3 
donut | 2 
pie  | 1 

不過,我努力使查詢命令是這樣的。我在這裏看過其他例子,但他們似乎過於複雜,因爲我猜測會是一件相當簡單的事情。

有沒有簡單的方法來實現這一目標?我是MySQL的新手,所以如果這是一個明顯的問題,我很抱歉。

在此先感謝您的想法!

P.S.我無法在此表上使用fulltext,因此我無法通過相關性排序結果。

+0

Table'MyISAM'或'InnoDB'?在MyISAM表中,即使不創建FULLTEXT索引,也可以使用一些FULLTEXT功能。 – Quassnoi 2011-04-13 15:21:08

+2

你有可能改變你的桌子嗎?與您的選擇字段中的逗號分隔列表,你打破規範化的規則... awm的表結構應該是你如果你可以改變它... – Leslie 2011-04-13 15:52:10

+0

謝謝你們。 Quassnoi,它是MyISAM。我不知道一些沒有'FULLTEXT'索引的功能仍然可用,所以感謝提示。萊斯利,是的,我最終選擇了這個解決方案。原始數據爲CSV格式,所以我認爲一張桌子可以。我錯了:) – Superangel 2011-04-14 09:31:50

回答

6

將你的數據分成兩個表格 - 一個定義甜點,一個定義選擇?這將使查詢更簡單和更快。

甜品表:

id | dessert 
------------ 
1 | pie 
2 | cake 
3 | donut 

選擇表:

id | choice 
----------- 
1 | apple pie 
1 | chocolate pie 
2 | chocolate cake 
2 | lemon cake 
2 | white chocolate cake 
2 | triple chocolate cake 
3 | frosted donut 
3 | chocolate donut 
3 | chocolate cream donut 

然後,你可以這樣做:

select `dessert`, count(*) as `matches` 
     from `desserts` join `choices` using (`id`) 
     where `choice` like '%chocolate%' 
     group by `id` 
     order by `matches` desc 
+0

謝謝awm!我剛分完桌子(實際上有10萬個「甜點」和170,000個'選擇')。無論如何,在經過一些快速測試之後:a)它完美地工作,並且b)比單表解決方案快29-42%。非常感謝您的明確指導和示例;我學到了很多。 – Superangel 2011-04-14 09:28:23

4

剛剝離出匹配的單詞,然後比較的差異字符串長度

SELECT id 
    , desert 
    , (LENGTH(choice) - LENGTH(REPLACE(choice,'chocolate',''))) 
    /LENGTH('chocolate') AS matches 
FROM desert_table 
WHERE choice LIKE '%chocolate%' 
ORDER BY 3 DESC 
+0

謝謝Sodved!這是一個非常聰明的方法;我不會想到使用字符串長度來計算匹配,並且它也增加了相對較少的開銷。最後,我選擇了上面的解決方案,因爲性能方面的好處,但如果我只需要使用一個表格,那麼您的解決方案就是完美的。再次感謝;這真的很有幫助! (對於任何其他使用混合大小寫字符串的情況,請記住'LOWER()''REPLACE()'值,否則會得到一些不正確的'0'匹配)。 – Superangel 2011-04-14 09:28:48