Reputation: 196639
I asked this question before and got a great working answer.
what is the query to get "related tags" like in stack overflow
but i realized that SOF actually takes it one step further as it supports multiple tag drilldown
what i mean is, if click on the tag C#, that will filter to 20,000 questions and it will show me all related tags on questions that also have C# as a tag.
but then, i can click on the tag "Collections" and now see total number of questions with the tag "C#" and "Collections". maybe that 500 questions
in addition, it will still show me related tags, which are tags that exist in questions which also have tag "C#" and "Collections"
and you can keep filtering down.
so the answer in the above link, only support 1 single tag.
in sql how would you get this to work to be able to completely drill down and show count of related tags and allow the user to keep choosing additional tags for drilldown.
Upvotes: 2
Views: 549
Reputation: 8648
SELECT t.tagName
FROM tags t INNER JOIN tagsBridge tb on t.id=tb.tagID
where tb.linkID in (
select tb.linkID from tagsBridge tb
where tb.tagID= @first_tag
intersect
select tb.linkID from tagsBridge tb
where tb.tagID= @second_tag
intersect
select tb.linkID from tagsBridge tb
where tb.tagID= @third_tag
intersect
select tb.linkID from tagsBridge tb
where tb.tagID= @fourth_tag
--- // you can continue
)
)
Upvotes: 0
Reputation: 41306
I'd use something like this as the first version. @FirstTagID
and @SecondTagID
must be sorted by ID. You can query on more tags by adding more joins to the inner query.
SELECT tagName
FROM tags
WHERE id IN (
SELECT tagID
FROM tagsBridge
WHERE linkID IN (
SELECT t1.linkID
FROM
tagsBridge t1
JOIN tagsBridge t2 ON t2.linkID=t1.linkID AND t2.tagID > t1.tagID
WHERE t1.tagID=@FirstTagID AND t2.tagID=@SecondTagID
)
AND tagID!=@FirstTagID AND tagID!=@SecondTagID
)
Or if you want to include the number of links:
SELECT t.tagName, count(*)
FROM
tags t
JOIN tagsBridge tb ON tb.tagID = t.id
WHERE
tb.linkID IN (
SELECT t1.linkID
FROM
tagsBridge t1
JOIN tagsBridge t2 ON t2.linkID=t1.linkID AND t2.tagID > t1.tagID
WHERE t1.tagID=@FirstTagID AND t2.tagID=@SecondTagID
)
AND t.tagID!=@FirstTagID AND t.tagID!=@SecondTagID
GROUP BY t.tagName
The same for three tags:
SELECT t.tagName, count(*)
FROM
tags t
JOIN tagsBridge tb ON tb.tagID = t.id
WHERE
tb.linkID IN (
SELECT t1.linkID
FROM
tagsBridge t1
JOIN tagsBridge t2 ON t2.linkID=t1.linkID AND t2.tagID > t1.tagID
JOIN tagsBridge t3 ON t3.linkID=t2.linkID AND t3.tagID > t2.tagID
WHERE t1.tagID=@FirstTagID AND t2.tagID=@SecondTagID AND t3.tagID=@ThirdTagID
)
AND t.tagID!=@FirstTagID AND t.tagID!=@SecondTagID AND t.tagID!=@ThirdTagID
GROUP BY t.tagName
Upvotes: 4
Reputation: 2170
Let's say you have a table called entity_tags
linking entities
with the tags
like this :
entity_id : INTEGER
tag_id : INTEGER
Let's say you user as selected N tags @1, @2, ... @N. To get the other tags associated with the results (and as a bonus, their frequency of occurence):
SELECT et.tag_id, COUNT(et.entity_id) as frequency FROM
entity_tags AS et
JOIN entity_tags AS et1 ON (et1.entity_id=et.entity_id AND et1.tag_id=@1)
...
JOIN entity_tags AS etN ON (etN.entity_id=et.entity_id AND etN.tag_id=@N)
WHERE et.tag_id NOT IN (@1, @2, ... @N)
GROUP BY et.tag_id;
Upvotes: 1