2011-03-04 53 views
3

在我的數據庫中,我有一個包含產品的表格和另一個包含與每個te產品關聯的標籤的表格。MYSQL與多個WHERE獲得最接近的匹配

當用戶查看產品的頁面時,我想顯示他所查看的最「最相關的」(或最接近的)產品。

所以我們假設產品標有5個不同的標籤。我想獲得具有相同5個標籤的產品,然後是具有相同5個標籤中的4個的標籤,然後是具有相同5個標籤中的3個的那些標籤,等等...

要做到這一點,我猜我必須創建一個或多個MYSQL查詢,但我甚至不知道從哪裏開始。

匹配相同的5個標籤很容易,我可以使用WHERE tag ='?' AND tag ='?'...但是我怎樣才能得到其他的(4/5,3/5,2/5,1/5)?

任何幫助將不勝感激!

乾杯 史蒂芬


編輯

@Orbits:我的標籤都在不同的行...如果不是我大概可以做一個文本匹配但這是這種情況。一個標記一行由(ID,標籤,PRODUCT_ID)

@ cusimar9:不同的表,如在後表示:P

@vbence:我相信這是儘可能簡單..這裏是..但是我沒有連接表

產品:

CREATE TABLE `products` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    ... 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

標籤:

CREATE TABLE `tags` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `type` varchar(70) NOT NULL, 
    `product_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=116 ; 
+0

都在同一領域的標籤?他們如何劃界? – Orbit 2011-03-04 14:52:42

+0

或者是單獨的表中的標籤? – cusimar9 2011-03-04 14:56:17

+0

請複製粘貼「CREATE TABLE」查詢的3個選擇,定義您的標記,產品和連接表。 (該產品的詳細信息可以省略)。 – vbence 2011-03-04 14:56:27

回答

3

字符串文字'Tag1'等等當然必須替換您的標籤。

SELECT products.id, COUNT(tags.id) AS match_level 
FROM products 
    LEFT JOIN tags ON tags.product_id = product.id 
WHERE tags.type IN ('Tag1', 'Tag2', 'Tag3', 'Tag4', 'Tag5') 
GROUP BY products.id 
ORDER BY match_level DESC 

如果您還沒有像這樣的索引,請將其添加到您的tags表中。沒有索引,你正在浪費資源。重要時刻。

CREATE INDEX multimatch ON tags (type, product_id); 
+2

...'tags.type IN('Tag1','Tag2','Tag3')' – Htbaa 2011-03-04 15:36:55

+0

@vbence @Mark我猜標籤的數量是可變的,5數字只是一個例子。 – 2011-03-04 15:54:33

+0

@Clodoaldo這裏也是一個例子,它可以改變ofc。我只是因爲這個問題而使用了5。 – vbence 2011-03-04 15:58:29

1
SELECT A.* 
    FROM (SELECT P.*, 
       P.Tag LIKE '%a%' AS Tag1, 
       P.Tag LIKE '%b%' AS Tag2, 
       P.Tag LIKE '%c%' AS Tag3, 
       P.Tag LIKE '%d%' AS Tag4, 
       P.Tag LIKE '%e%' AS Tag5 
      FROM `products` P 
      WHERE P.Tag LIKE '%a%' 
      OR P.Tag LIKE '%b%' 
      OR P.Tag LIKE '%c%' 
      OR P.Tag LIKE '%d%' 
      OR P.Tag LIKE '%e%' 
     ) A 
ORDER BY A.Tag1+A.Tag2+A.Tag3+A.Tag4+A.Tag5 DESC 
+0

我會試一試!謝謝 – 2011-03-04 15:07:30

+0

您必須重新構建查詢以跨兩個表格進行連接 - 在添加表格詳細信息之前,我將其作爲一般原則發佈 - 但該原則仍應可行。返回P.Tag LIKE'%a%'AS Tag1在內部查詢中給出0或1,外部只是將這些結果添加並按降序顯示。 – 2011-03-04 15:13:23

+0

它可能不一定是最乾淨的方法,但它是第一個想到的,它確實工作 – 2011-03-04 15:13:50

0
select products.id, count(*) as matches 
from products 
inner join tags on products.id = tags.product_id 
inner join (
    select t.id 
    from products p 
    inner join tags t on p.id = t.product_id 
    where p.id = $product_id 
) product_tags on tags.id = product_tags.id 
group by products.id 
order by products.id desc 
1

Simples:

SELECT related.id, count(*) as matches 
FROM products related, 
    tags rel_tags, 
    tags this_tags 
WHERE this_tags.product_id=$product_id_for_this_product 
AND this_tags.type=rel_tags.type 
AND rel_tags.product_id<>this_tags.product_id 
AND rel_tags.product_id=related.id 
GROUP BY related_id 
ORDER BY count(*) DESC