I'm trying different JOIN queries, but I'm not getting result I'm looking for.
I've got 2 tables:
Table 1: **StockItemShort**    
ItemID  | Code          | Name    
 432724 | CK002-16-09   | Green Daisy Pearl Earrings
 432759 | CK002-16-149  | Emerald Crystal Centre Daisy Earrings  
Table 2: **StockItemCatSearchValueShort**
ItemID |    SearchValueID
432724 |    388839
432724 |    389061
432724 |    390269
432724 |    389214
432759 |    388839
432759 |    389051
432759 |    390269
432759 |    389214
I can't get result I'm looking for.
I'd like to get following result:
ItemID  | Code  | Name  | SearchValueID | SearchValueID | SearchValueID | SearchValueID 
432724  | CK002-16-09   | Green Daisy Pearl Earrings    | 388839    | 389061    | 390269    | 389214
432759  | CK002-16-149  | Emerald Crystal Centre Daisy Earrings | 388839    | 389051    | 390269    | 389214
                You cannot have dynamic number of column like that, but you can concatenate your data into string:
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;
or you can pivot rows with PIVOT command or manually (I prefer latter approach, it just seems more flexible for me, but pivot can greatly reduce amount of code in certain situations):
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
You also can turn previous statement into dynamic SQL like this:
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
sql fiddle demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With