Brian Presler's pseudo-code is pretty close, with the exception of a few association issues. Here is what I think it looks like:
-- The sample data from the problem. declare @SearchString varchar(32) = 'TV'; declare @RelatedItemsTable table ( [Item] varchar(32), [Accessory] varchar(32) ); insert @RelatedItemsTable values ('TV', 'Antennae'), ('TV', 'Power Cord'), ('TV', 'Remote'), ('Laptop', 'Power Cord'), ('Laptop', 'Carrying Case'), ('Camera', 'Carrying Case'), ('Camera', 'Lens'), ('iPod', 'Headphones'); -- This table will hold your results. declare @SearchResults table ( [Item] varchar(32), [Accessory] varchar(32) ); -- Base case: look for any item or accessory that matches the search string. -- I'm not sure whether you want to search items only or accessories also; -- adjust as needed. insert @SearchResults select * from @RelatedItemsTable where [Item] like @SearchString or [Accessory] like @SearchString; while @@rowcount > 0 begin -- The recursive case: look for new records where... insert @SearchResults select [New].[Item], [New].[Accessory] from @RelatedItemsTable [New] inner join @SearchResults [Old] on -- ... the new record is an item using the same kind of accessory as -- an existing item, or... [New].[Accessory] = [Old].[Accessory] or -- ... the new record is an accessory for the same kind of item as an -- existing accessory, and... [New].[Item] = [Old].[Item] where -- ... this record doesn't yet appear in the result set. not exists ( select 1 from @SearchResults [Existing] where [Existing].[Accessory] = [New].[Accessory] and [Existing].[Item] = [New].[Item] ); end; select * from @SearchResults;
SQL Server has a mechanism for recursive queries - a recursive CTE - but I could not implement this example using one of these because I could not implement the NOT EXISTS part of the above query.
Joe farrell
source share