views:

226

answers:

4

I have my tags desinged like this in my database:

Table: Item 
Columns: ItemID, Title, Content 

Table: Tag 
Columns: TagID, Title 

Table: ItemTag 
Columns: ItemID, TagID



//example -- this is the right sidebar of stackoverflow
c# × 59279
sql × 14885
asp.net-mvc × 9123
linq × 4337
tags × 339

if I wanted to know the count of each tag such as how stackoverflow counts their tags how would I do it? What kind of query would I perform. I am open to both regular sql and linq

+3  A: 
select t.Title, count(it.TagID) as TagCount
from Tag t
  inner join ItemTag it on t.TagID = it.TagID
  inner join Item i on it.ItemID = i.ItemID
where i.ItemID = @currentItemID -- optional, if you only want current page
group by t.Title
Noah Heldman
Nice! Will this hard on the database if I have thousands of posts and tags?
Luke101
Counting on every query will kill your database when there will be more than 10 rows per table. ;) Angelbit posted the best solution.
Crozin
I actually agree that Angelbit's approach is better... it's the same way the large-scale distributed databases (e.g. BigTable) recommend dealing with reporting on item counts. I was just trying to write the query you were asking for. :)
Noah Heldman
A: 

You can use another column in Item to store tag count and synchronize it when add or remove tags.

Darmen
A: 
SELECT title, count(*) FROM tag
JOIN itemtag ON itemtag.tagid = tag.tagid
GROUP BY title
rmn
+4  A: 

Add another column in the table Tag that work as counter. When you add or remove a tag from an item you update the counter (in other words, when add a row on Itemtag increment the counter on Tag table, when remove decrement the counter)

add tag to item:

INSERT INTO Itemtag (itemid,tagid) VALUES ('$itemid','$tagid');
UPDATE Tag SET counter=counter+1 WHERE tagid='$tagid';

remove tag from item

DELETE FROM Itemtag WHERE itemid='$itemid' AND tagid='$tagid';
UPDATE Tag SET counter=counter-1 WHERE tagid='$tagid';

retrieve item tags with counter

SELECT t.title, t.counter FROM Itemtag AS it JOIN Tag AS t ON t.idtag=it.tagid 
WHERE it.itemid='$itemid'
Angelbit
thanks angel bit
Luke101