Du kan ikke have sådan et dynamisk antal kolonner, men du kan sammenkæde dine data ind i streng:
select
s.ItemID, s.Code, s.Name,
stuff(
(
select ', ' + CAST(sv.SearchValueID AS VARCHAR)
from ItemSearch as sv
where sv.ItemID = s.ItemID
for xml path(''), type
).value('.', 'nvarchar(128)')
, 1, 2, '') as SearchValues
from Item as s;
eller du kan pivotere rækker med PIVOT command
eller manuelt (Jeg foretrækker sidstnævnte tilgang, det virker bare mere fleksibelt for mig, men pivot
kan i høj grad reducere mængden af kode i visse situationer ):
with cte as (
select
*,
row_number() over(partition by sv.ItemID order by sv.SearchValueID) as row_num
from ItemSearch as sv
)
select
s.ItemID, s.Code, s.Name,
max(case when sv.row_num = 1 then sv.SearchValueID end) as SearchValueID1,
max(case when sv.row_num = 2 then sv.SearchValueID end) as SearchValueID2,
max(case when sv.row_num = 3 then sv.SearchValueID end) as SearchValueID3,
max(case when sv.row_num = 4 then sv.SearchValueID end) as SearchValueID4
from Item as s
inner join cte as sv on sv.ItemID = s.ItemID
group by s.ItemID, s.Code, s.Name
Du kan også omdanne tidligere sætning til dynamisk SQL sådan her:
declare @stmt nvarchar(max)
select
@stmt =
isnull(@stmt + ',','') +
'max(case when sv.row_num = ' + cast(rn as nvarchar(max)) +
' then sv.SearchValueID end) as SearchValueID' + cast(rn as nvarchar(max))
from (
select distinct row_number() over(partition by ItemID order by SearchValueID) as rn
from ItemSearch
) as a
select @stmt = '
with cte as (
select
*,
row_number() over(partition by sv.ItemID order by sv.SearchValueID) as row_num
from ItemSearch as sv
)
select
s.ItemID, s.Code, s.Name,' + @stmt + '
from Item as s
inner join cte as sv on sv.ItemID = s.ItemID
group by s.ItemID, s.Code, s.Name;'
exec dbo.sp_executesql @stmt = @stmt