You can try the below query. Here I have used a simple query shown below to get all the records that exist in both tables.
SELECT DISTINCT DataSetId AS SearchId, FindinValues FROM ( Select TableA.*, TableB.DataSetId as FindinValues, ROW_NUMBER() OVER (PARTITION By TableB.DataSetId Order By TableB.DataSetId) RN from TableA inner join TableB on TableA.ColumnA = TableB.ColumnA and TableA.ColumnB = TableB.ColumnB )a where RN = (Select Count(*) from tableA)
The output of the above query is as shown below.
SearchId FindinValues ------------------------ 101 301 101 501
Now to get the above table into comma separated group by search id you have two choices in terms of simplicity i.e., you can consider your above query as a table or you can insert the above query records into a temporary table and run the below query on that.
-- To get the data in comma separated which exists in both the table. SELECT SearchId, FindinValues = STUFF((SELECT ', ' + Cast(FindinValues as Varchar(20)) FROM (SELECT DISTINCT DataSetId AS SearchId, FindinValues FROM ( Select TableA.*, TableB.DataSetId as FindinValues, ROW_NUMBER() OVER (PARTITION By TableB.DataSetId Order By TableB.DataSetId) RN from TableA inner join TableB on TableA.ColumnA = TableB.ColumnA and TableA.ColumnB = TableB.ColumnB )a where RN = (Select Count(*) from tableA)) b WHERE b.SearchId = a.SearchId FOR XML PATH('')), 1, 2, '') FROM (SELECT DISTINCT DataSetId AS SearchId, FindinValues FROM ( Select TableA.*, TableB.DataSetId as FindinValues, ROW_NUMBER() OVER (PARTITION By TableB.DataSetId Order By TableB.DataSetId) RN from TableA inner join TableB on TableA.ColumnA = TableB.ColumnA and TableA.ColumnB = TableB.ColumnB )a where RN = (Select Count(*) from tableA)) a GROUP BY SearchId
This will give output as shown below.
SearchId FindinValues ------------------------ 101 301, 501
You can find the live demo here.
Here is another way with a shorter code.
SELECT DISTINCT DataSetId AS SearchId, FindinValues into #TempResult FROM ( Select TableA.*, TableB.DataSetId as FindinValues, ROW_NUMBER() OVER (PARTITION By TableB.DataSetId Order By TableB.DataSetId) RN from TableA inner join TableB on TableA.ColumnA = TableB.ColumnA and TableA.ColumnB = TableB.ColumnB )a where RN = (Select Count(*) from tableA) -- To get the data in comma separated which exists in both the table. Select * from #TempResult SELECT SearchId, FindinValues = STUFF((SELECT ', ' + Cast(FindinValues as Varchar(10)) FROM #TempResult b WHERE b.SearchId = a.SearchId FOR XML PATH('')), 1, 2, '') FROM #TempResult a GROUP BY SearchId
You can find this demo here. This will run in the lower version of SQL Server also.