Step 1 is to go and find the person that designed this table structure (even if it is you) then whack them round the head with a stick.
Step 2 is to redesign the tables, a junction table is what is required here, not stuffing multiple integers into a single varchar column. For good measure at the end of step two you should hit the original designer with a stick again.
CREATE TABLE tbl_Main_Holding_Requirements
(
MainHoldingID INT NOT NULL, --FK TO `tbl_main_Holding`
FeatureID INT NOT NULL -- FK TO Require `tbl_Features`
);
Now, each requirement represents a row in this table, rather than a new item on your list, so your join is now simple:
SELECT *
FROM dbo.tbl_Main_Holding AS rm
LEFT JOIN dbo.tbl_Main_Holding_Requirements AS r
ON r.MainHoldingID = rm.ID
LEFT JOIN [dbo].[tbl_Features] AS f
ON f.ID = r.FeatureID;
If you need to bring this back up to a comma delimited list, then you can do it in the presentation layer, or with SQL-Server's XML Extensions:
SELECT *,
Features = STUFF(f.Features.value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM dbo.tbl_Main_Holding AS rm
OUTER APPLY
( SELECT CONCAT(',', f.Description)
FROM dbo.tbl_Main_Holding_Requirements AS r
INNER JOIN [dbo].[tbl_Features] AS f
ON f.ID = r.FeatureID
WHERE r.MainHoldingID = rm.ID
FOR XML PATH(''), TYPE
) f (Features);
If step two is not possible, then you can get around this using LIKE
:
SELECT *
FROM dbo.tbl_Main_Holding AS rm
LEFT JOIN [dbo].[tbl_Features] AS f
ON ',' + rm.Requirements + ',' LIKE '%,' + CONVERT(VARCHAR(10), f.ID) + ',%';
Once again, if the features need to be reduced back to a single row, then you can use XML extensions again:
SELECT *,
Features = STUFF(f.Features.value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM dbo.tbl_Main_Holding AS rm
OUTER APPLY
( SELECT CONCAT(',', f.Description)
FROM [dbo].[tbl_Features] AS f
WHERE ',' + rm.Requirements + ',' LIKE '%,' + CONVERT(VARCHAR(10), f.ID) + ',%'
FOR XML PATH(''), TYPE
) f (Features);
Another option is to split the comma separated values into a list using some kind of Split
function, but as the testing in this article shows, if you don't need to access the individual values from the list, it is more efficient to just use LIKE
.