|
rdaunce
Starting Member
7 Posts |
Posted - 2009-10-14 : 21:02:11
|
| I have an issue that I have been trying to solve and I haven't been able to find much info on different approaches to take. Basically, I have 4 tables - statements, statement_tag, tag, and tagtype. There are a number of statements and then a number of tags with different types. Tags are applied to statements using the statement_tag table. Here is example data I am working with:declare @statement table( statementid int, name varchar(255))insert into @statement (statementid, name) values (1, 'statement 1')insert into @statement (statementid, name) values (2, 'statement 2')insert into @statement (statementid, name) values (3, 'statement 3')insert into @statement (statementid, name) values (4, 'statement 4')insert into @statement (statementid, name) values (5, 'statement 5')insert into @statement (statementid, name) values (6, 'statement 6')insert into @statement (statementid, name) values (7, 'statement 7')insert into @statement (statementid, name) values (8, 'statement 8')insert into @statement (statementid, name) values (9, 'statement 9')declare @tagtype table( tagtypeid int, tagtype varchar(50))insert into @tagtype (tagtypeid, tagtype) values (1, 'type 1')insert into @tagtype (tagtypeid, tagtype) values (2, 'type 2')insert into @tagtype (tagtypeid, tagtype) values (3, 'type 3')declare @tag table( tagid int, tagtypeid int, tag varchar(50))insert into @tag (tagid, tagtypeid, tag) values (1, 1, 'tag 1')insert into @tag (tagid, tagtypeid, tag) values (2, 1, 'tag 2')insert into @tag (tagid, tagtypeid, tag) values (3, 1, 'tag 3')insert into @tag (tagid, tagtypeid, tag) values (4, 2, 'tag 4')insert into @tag (tagid, tagtypeid, tag) values (5, 2, 'tag 5')insert into @tag (tagid, tagtypeid, tag) values (6, 2, 'tag 6')insert into @tag (tagid, tagtypeid, tag) values (7, 3, 'tag 7')insert into @tag (tagid, tagtypeid, tag) values (8, 3, 'tag 8')declare @statement_tag table( statementid int, tagid int)insert into @statement_tag (statementid, tagid) values (1, 1)insert into @statement_tag (statementid, tagid) values (2, 1)insert into @statement_tag (statementid, tagid) values (3, 1)insert into @statement_tag (statementid, tagid) values (4, 2)insert into @statement_tag (statementid, tagid) values (5, 2)insert into @statement_tag (statementid, tagid) values (6, 2)insert into @statement_tag (statementid, tagid) values (7, 3)insert into @statement_tag (statementid, tagid) values (8, 3)insert into @statement_tag (statementid, tagid) values (9, 3)insert into @statement_tag (statementid, tagid) values (1, 4)insert into @statement_tag (statementid, tagid) values (2, 5)insert into @statement_tag (statementid, tagid) values (3, 6)insert into @statement_tag (statementid, tagid) values (4, 4)insert into @statement_tag (statementid, tagid) values (5, 5)insert into @statement_tag (statementid, tagid) values (6, 6)insert into @statement_tag (statementid, tagid) values (7, 4)insert into @statement_tag (statementid, tagid) values (8, 5)insert into @statement_tag (statementid, tagid) values (9, 6)insert into @statement_tag (statementid, tagid) values (1, 7)insert into @statement_tag (statementid, tagid) values (2, 7)insert into @statement_tag (statementid, tagid) values (3, 7)insert into @statement_tag (statementid, tagid) values (4, 7)insert into @statement_tag (statementid, tagid) values (5, 7)insert into @statement_tag (statementid, tagid) values (6, 8)insert into @statement_tag (statementid, tagid) values (7, 8)insert into @statement_tag (statementid, tagid) values (8, 8)insert into @statement_tag (statementid, tagid) values (9, 8)The user will be supplying a list of tags that will be stored in a table. This list will change based on user actions, so the solution needs to be adaptable to work with any table of tagids.declare @tags table( tagid int)insert into @tags (tagid) values (1) --tagtype 1insert into @tags (tagid) values (2) --tagtype 1insert into @tags (tagid) values (4) --tagtype 2What I need to do is to select all statements that match at least one of the provided tags for each of the tag types that are relevent. In the above example, only two of the tagtypes are represented, however, this will not always be the case. In some instances only one tagtype or all tagtypes are used. I need to ignore tagtypes that are not used.For the above example, I need to return the following all statements that match types ( ( 1 or 2 ) and 4 ):Statement 1 (matches tagid 1, 4)Statement 4 (matches tagid 2, 4)The best I have been able to come up with is the following:declare @vartags table( tagtypeid int, tagid int)declare @varstatement table( statementid bigint)declare @vartagtype table( tagtypeid int)insert into @vartags select t.tagtypeid, t.tagid from @tags ts inner join @tag t on ts.tagid = t.tagidinsert into @vartagtypeselect distinct tagtypeid from @vartagsdeclare @tagtypeid intselect top 1 @tagtypeid=tagtypeid from @vartagtypeif @tagtypeid is not null begin insert into @varstatement select s_t.statementid from @statement_tag s_t where s_t.tagid in (select tagid from @vartags where tagtypeid = @tagtypeid) delete from @vartagtype where tagtypeid = @tagtypeid select top 1 @tagtypeid=tagtypeid from @vartagtype while @@rowcount > 0 begin delete from @statement where statementid not in ( select s.statementid from @statement_tag s_t join @statement s on s.statementid = s_t.statementid where s_t.tagid in (select tagid from @vartags where tagtypeid = @tagtypeid) ) endendselect * from @varstatement vs join @statement s on s.statementid = vs.statementidWhile this works, I don't think that it is the most efficient way to go about this. I'm really struggling to come up with an alternative way to handle the list of tags and the fact that the number of tags provided as well as the number of corresponding tagtypes will vary.Can anyone suggest a better solution?--Bob |
|