2010-01-26 2 views
3

На странице с указанием конкретного объекта мне нужно отобразить связанные объекты для этого объекта на основе тегов. 'Объект с наибольшим количеством соответствующих тегов должен быть наверху. В принципе, мне нужно определить количество тегов для каждого объекта, которые соответствуют объекту на странице, и отображать верхние результаты.mysql Выбрать связанные объекты по тегам

Моя дб схема:

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


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


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

Я предполагаю, что вы не хотите включать сам объект в результирующий набор? –

ответ

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.*) 

В основном мы начнем с создания оператора выбора, который будет получать все теги, что ваш объект принадлежит, то мы используйте это как производную таблицу и присоедините ее, чтобы отфильтровать любые другие теги во внешнем выборе. Наконец, мы группируем объект object_id и делаем COUNT (*) в таблице тегов, чтобы найти множество совпадающих тегов.

РЕДАКТИРОВАТЬ: забыл предложение where снаружи, чтобы избавиться от вашего исходного объекта.

Смежные вопросы