As has already been hinted, you can use PIVOT in the SQL to get the data the way you want it - an example of how to do that can be found at
Simple Way To Use Pivot In SQL Query[
^]
Here is a worked example for your scenario - all in SQL. Firstly some sample data
declare @products2 table (prodID int identity (1,1), prod varchar(50));
declare @model table (modID int identity(1,1), prodID int, prodName varchar(50));
insert into @products2 (prod) values ('Product1'),('Product2'),('Product3');
insert into @model (prodID, prodName) values (1,'P1Mod1'),(1,'P1Mod2'),(2,'P2Mod1'),(3,'P3Mod1'),(3,'P3Mod2'),(3,'P3Mod3');
(HINT: always provide sample data and the expected results from that data to get the best chance of an answer to your question)
The first thing we need is some way of identifying which "column" each of the models needs to be in. Not all products have the same amount of models. I'm going to use the ROW_NUMBER() function just to give them an arbitrary name. I'm also going to tidy up the columns that I'm retrieving from the tables to avoid duplication e.g.
SELECT a.prodID, a.prod, b.modID, b.prodName, ROW_NUMBER() OVER (PARTITION BY a.prodID ORDER BY a.prodID, b.modID) AS rn
FROM @products2 a
INNER JOIN @model b ON a.prodID=b.prodID
(HINT: Instead of using SELECT * .. in your queries, always list the columns you require. It avoids duplication and protects your code from database schema changes in the future)
The results from that query are
prodID prod modID prodName rn
1 Product1 1 P1Mod1 1
1 Product1 2 P1Mod2 2
2 Product2 3 P2Mod1 1
3 Product3 4 P3Mod1 1
3 Product3 5 P3Mod2 2
3 Product3 6 P3Mod3 3
In my example the maximum number of models per product is 3, but that might vary. I don't want to get into the complexity of dynamic SQL here so I'm going to assume in the rest of my code that there could be up to 5 models per product. Just putting this out here now so you are aware of the possible pitfalls.
If you follow that article through you will notice that you need to have an aggregate function in your pivot. Unfortunately you can't use things like concatenate or sum on varchars (the model name) so I've used MAX() here..
select prod, [1],[2],[3],[4],[5]
from
(
SELECT a.prodID, a.prod, b.modID, b.prodName,
ROW_NUMBER() OVER (PARTITION BY a.prodID ORDER BY a.prodID, b.modID) AS rn
FROM @products2 a
INNER JOIN @model b ON a.prodID=b.prodID
) src
PIVOT
(
max(prodName) for rn in ([1],[2],[3],[4],[5])
) pvt
That gives me the results
prod 1 2 3 4 5
Product1 P1Mod1 NULL NULL NULL NULL
Product1 NULL P1Mod2 NULL NULL NULL
Product2 P2Mod1 NULL NULL NULL NULL
Product3 P3Mod1 NULL NULL NULL NULL
Product3 NULL P3Mod2 NULL NULL NULL
Product3 NULL NULL P3Mod3 NULL NULL
Almost there, but not quite!
To get rid of all those NULL values, and to get to a single row per product, I'm going to use a GROUP BY statement in my final SQL e.g.
select prod, max([1]) as [1],max([2]) as [2],max([3]) as [3], max([4]) as [4], max([5]) as [5]
from
(
SELECT a.prodID, a.prod, b.modID, b.prodName,
ROW_NUMBER() OVER (PARTITION BY a.prodID ORDER BY a.prodID, b.modID) AS rn
FROM @products2 a
INNER JOIN @model b ON a.prodID=b.prodID
) src
PIVOT
(
max(prodName) for rn in ([1],[2],[3],[4],[5])
) pvt
group by prod
Which gives the results
prod 1 2 3 4 5
Product1 P1Mod1 P1Mod2 NULL NULL NULL
Product2 P2Mod1 NULL NULL NULL NULL
Product3 P3Mod1 P3Mod2 P3Mod3 NULL NULL
You can tidy up the NULL values in this output in your presentation layer. If you want the results as a comma separated list then look at using the
CONCAT function[
^]