Home Forums SQL Server 7,2000 T-SQL Use Results from a Cross Join for dynamic SQL RE: Use Results from a Cross Join for dynamic SQL

  • OK, here's my idea. I am still using a cursor to define the product combos. However, once defined, the combo list only needs to be changed if products are added or dropped.

    First, assume the products are in #tmp_prod, and that the prod column will identify them in the response table.

    ----------

    create table #prod_combo

    (combo_id int, prod char(1))

    go

    declare @counter int

    declare @cur_prod char(1)

    declare @max_id int

    set @counter = 1

    declare c1 cursor for select prod from #tmp_prod

    open c1

    fetch c1 into @cur_prod

    if (@@FETCH_STATUS = 0)

    BEGIN

    insert into #prod_combo VALUES (1, @cur_prod)

    fetch c1 into @cur_prod

    END

    while (@@FETCH_STATUS = 0)

    begin

    select @max_id = MAX(combo_id) from #prod_combo

    insert into #prod_combo select combo_id + @max_id, @cur_prod from #prod_combo

    UNION select combo_id + @max_id, prod from #prod_combo

    UNION select (2 * @max_id) + 1, @cur_prod

    fetch c1 into @cur_prod

    end

    close c1

    deallocate c1

    ----------

    We create a flat table to hold all the possible product combinations. Each combination has a unique ID, and one row for each product in that combination.

    It makes life a little easier to have a table containing the distinct combo IDs:

    ----------

    select distinct combo_id into #tmp_combo_ids from #prod_combo

    ----------

    Once we have this, processing the responses becomes easy. Given the following response table:

    ----------

    create table #tmp_resp

    (resp_id int, prod char(1), yn char(3))

    go

    insert into #tmp_resp

    select 1, 'A', 'Yes'

    UNION

    select 1, 'B', 'No'

    UNION

    select 1, 'C', 'Yes'

    UNION

    select 2, 'A', 'Yes'

    UNION

    select 2, 'B', 'Yes'

    UNION

    select 2, 'C', 'No'

    UNION

    select 3, 'A', 'Yes'

    UNION

    select 3, 'B', 'No'

    UNION

    select 3, 'C', 'Yes'

    UNION

    select 4, 'A', 'Yes'

    UNION

    select 4, 'B', 'Yes'

    UNION

    select 4, 'C', 'Yes'

    ----------

    we can process the responses with the following statement:

    ----------

    select m.combo_id, count(distinct r.resp_id) AS "Would Buy", (select count(*) from #prod_combo where combo_id = m.combo_id) as "Products in Combo"

    from #tmp_combo_ids m, #tmp_resp r

    where r.yn = 'Yes'

    and r.prod in (select prod from #prod_combo where combo_id = m.combo_id)

    group by m.combo_id

    ----------

    which yields:

    combo_id Would Buy Products in Combo

    1 4 1

    2 4 2

    3 2 1

    4 4 2

    5 4 3

    6 4 2

    7 3 1

    I'll leave manipulating these results to find the best combo as an exercise for the reader 🙂

    RD Francis


    R David Francis