@ YogeshSharma предоставил отличный ответ.
То же самое сделано с использованием Pivot
; SQL Fiddle Demo .
Функционально нет разницы между двумя ответами.Однако решение Йогеша проще для понимания и работает лучше;так что лично я бы выбрал это ... Я включил этот ответ только потому, что вы упомянули PIVOT в вопросе:
select ft.Id
, ft.IdCust
, ft.Ref
, x.Stock1
, x.Code1
, x.Price1
, x.Stock2
, x.Code2
, x.Price2
from FirstTable ft
left outer join (
select Ref
, max([Stock1]) Stock1
, max([Stock2]) Stock2
, max([Code1]) Code1
, max([Code2]) Code2
, max([Price1]) Price1
, max([Price2]) Price2
from
(
select Ref
, Id Stock
, Code
, Price
, ('Stock' + cast(Row_Number() over (partition by Ref order by Id, Code) as nvarchar)) StockLineNo
, ('Code' + cast(Row_Number() over (partition by Ref order by Id, Code) as nvarchar)) CodeLineNo
, ('Price' + cast(Row_Number() over (partition by Ref order by Id, Code) as nvarchar)) PriceLineNo
from SecondTable
) st
pivot (max(Stock) for StockLineNo in ([Stock1],[Stock2])) pvtStock
pivot (max(Code) for CodeLineNo in ([Code1],[Code2])) pvtCode
pivot (max(Price) for PriceLineNo in ([Price1],[Price2])) pvtPrice
Group by Ref
) x
on x.Ref = ft.Ref
order by ft.Ref
Как и решение Йогеша, оно будет обрабатывать столько столбцов, сколько вы укажете;он не будет динамически изменять количество столбцов в соответствии с данными.Для этого вам нужно сделать динамический SQL.Тем не мение;если вам нужно сделать это, более вероятно, что вы пытаетесь решить проблему неправильно ... так что подумайте над своим дизайном / определите, действительно ли вам нужны дополнительные столбцы для результата, а не дополнительные строки / какой-то альтернативный подход ...
Вот реализация Dynamic SQL, основанная на ответе @ YogeshSharma: DBFiddle
declare @sql nvarchar(max) = 'select id, IdCust, Ref'
select @sql = @sql + '
,max(case when Seq = 1 then stock end) as [Stock' + rowNumVarchar + ']
,max(case when Seq = 1 then code end) as [Code' + rowNumVarchar + ']
,max(case when Seq = 1 then price end) as [Price' + rowNumVarchar + ']
'
from
(
select distinct cast(row_number() over (partition by ref order by ref) as nvarchar) rowNumVarchar
from second s
) z
set @sql = @sql + '
from (select f.*, s.Id Stock, s.Code, s.Price,
row_number() over (partition by f.Ref order by s.id) as Seq
from first f
inner join second s on s.Ref = f.Ref
) t
group by id, IdCust, Ref;
'
print @sql --see what the SQL produced is
exec (@sql)
(Вот ссылка SQL Fiddle для этогоодин, но он не работает, несмотря на то, что SQL действителен