2010-01-26 64 views
3

在顯示特定對象的頁面上,我需要根據標籤顯示該對象的相關對象。 '最匹配匹配標籤的對象應該位於頂部。基本上我需要確定每個對象與頁面上的對象匹配的標籤數量,並顯示最佳結果。mysql通過標籤選擇相關對象

我的DB模式:

Table Object 
------------ 
    id 
    name 


Table Tagset 
------------- 
    object_id 
    tag_id 


Table Tag 
------------ 
    id 
    name 
+0

我假設你不想將對象本身包含在結果集中? – 2010-01-26 22:09:13

回答

2

這應該做你想要什麼:

SELECT object.name, COUNT(*) AS tag_count 
FROM tagset T1 
JOIN tagset T2 
ON T1.tag_id = T2.tag_id AND T1.object_id != T2.object_id 
JOIN object 
ON T2.object_id = object.id 
WHERE T1.object_id = 1 
GROUP BY T2.object_id 
ORDER BY COUNT(*) DESC 

結果:

'object2', 2 
'object3', 1 

使用這個測試數據:

CREATE TABLE object (id int NOT NULL, name nvarchar(100) NOT NULL); 
INSERT INTO object (id, name) VALUES 
(1, 'object1'), 
(2, 'object2'), 
(3, 'object3'); 

CREATE TABLE tagset (object_id int NOT NULL, tag_id int NOT NULL); 
INSERT INTO tagset (object_id, tag_id) VALUES 
(1, 1), 
(1, 2), 
(1, 3), 
(2, 1), 
(2, 3), 
(3, 2), 
(3, 4), 
(3, 5); 
0
select t.id, t.name 
from tag t 
inner join 
(
    select tag_id, count(tag_id) as counttags 
    from tagset 
    where object_id = <some expression to indicate the current object id> 
    group by tag_id 
) g 
    on t.id = g.tag_id 
    order by g.counttags desc 
1

顯然未經測試,但它應該工作,或至少讓你在正確的軌道上:

SELECT ts.object_id, o.name, COUNT(ts.*) as matching_tags 
FROM Tagset ts 
INNER JOIN 
    (SELECT tag_id 
    FROM Tagset 
    WHERE object_id = <your object id>) otags ON ts.tag_id = otags.tag_id 
INNER JOIN Object o ON ts.object_id = o.id 
WHERE ts.object_id <> <your object id> 
GROUP BY ts.object_id, o.name 
ORDER BY COUNT(ts.*) 

基本上我們用創造一個select語句,將讓你的對象所屬的所有標籤開始,那麼我們使用它作爲派生表並加入它以過濾掉外部選擇中的任何其他標記。最後,我們對object_id進行分組,並在tagset表上做一個COUNT(*)來找出許多匹配的標籤。

編輯:忘了在外面的where子句擺脫你的源對象。