2013-10-03 7 views
0

Я как бы выбрасываю град Мэри здесь, когда схожу с ума, пытаясь понять, как правильно это записать. Я искал рядом и далеко и не нашел что-то, что сделало этот «щелчок» для меня еще.Преобразование SELECT с 2 JOINS и COUNT в инструкцию UPDATE

Вот ситуация: Там в 3 таблицы (столбцы, участвующие в круглых скобках):

  • Prods (prod_id PK, prod_grp_id)
  • prod_grps (prod_grp_id PK, prod_grp_mgr_nm)
  • prod_grp_prods (prod_id, prod_grp_id)

Продукт может принадлежать более чем одному prod_grp. Например, бейсбол может быть в спортивном prod_grp, который может иметь prod_grp_mgr_nm = "AssMGR_Bill", а также находящийся в группе general_merch с prod_grp_mgr_nm = "LeadMGR_Jake". Мне нужно пройти каждый элемент в таблице prods и обновить значение «prod_grp_id» для каждого элемента, чтобы он содержал prod_group_id, которым управляет кто-то с «LeadMGR» в своем prod_grp_mgr_nm. Я хочу обновить prods только тогда, когда есть только один prod_grp с prod_grp_mgr_nm, содержащий «LeadMGR». Цель здесь - связать каждый продукт с группой, управляемой ведущим менеджером, если существует один (и только один).

До сих пор я получил эту ЗЕЬЕСТ:

SELECT prods.prod_id 
    FROM prods p 
    INNER JOIN prod_grp_prods pgp 
    ON prod.prod_id = pgp.prod_id 
    INNER JOIN prod_grps pg 
    ON pgp.prod_grp_id = pg.acct_grp_id 
    WHERE pg.prod_grp_mgr_nm LIKE '%LeadMGR%' 
    GROUP BY p.prod_id HAVING COUNT(p.prod_id) = 1 
    ORDER BY p.prod_id` 

Это возвращает все prod_ids, нуждающиеся в обновлении.

+0

Когда-либо слышал о SQLFiddle? ОЧЕНЬ ПОЛЕЗНАЯ ... специально для тестирования совместно. – DevlshOne

ответ

0

Я попытался воспроизвести ваши вопросы ниже. Я использовал подзапрос для обновления таблицы prods. Надеюсь, это повторит ваши проблемы.

create table #prods (prod_id int PRIMARY KEY, prod_grp_id int) 
create table #prod_grps (acct_grp_id int PRIMARY KEY, prod_grp_mgr_nm varchar(200)) 
create table #prod_grp_prods (prod_id int , prod_grp_id int) 

-- insert testing data 
insert into #prods values (1, null), (2,null), (3, null) 
insert into #prod_grps values (999, 'AssMGR_Bill'), (998, 'LeadMGR_Jake'), (995, 'LeadMGR_Jake') 
insert into #prod_grp_prods values (1, 999), (2, 995), (3, 999), (1,998) 

-- original query 
SELECT p.prod_id, pgp.prod_grp_id 
    FROM #prods p 
    INNER JOIN #prod_grp_prods pgp 
    ON p.prod_id = pgp.prod_id 
    INNER JOIN #prod_grps pg 
    ON pgp.prod_grp_id = pg.acct_grp_id 
    WHERE pg.prod_grp_mgr_nm LIKE '%LeadMGR%' 
    GROUP BY p.prod_id , pgp.prod_grp_id 
    HAVING COUNT(p.prod_id) = 1 
    ORDER BY p.prod_id 

-- update query 
update #prods set prod_grp_id = t.prod_grp_id 
from 
(
    SELECT p.prod_id, pgp.prod_grp_id 
    FROM #prods p 
    INNER JOIN #prod_grp_prods pgp 
    ON p.prod_id = pgp.prod_id 
    INNER JOIN #prod_grps pg 
    ON pgp.prod_grp_id = pg.acct_grp_id 
    WHERE pg.prod_grp_mgr_nm LIKE '%LeadMGR%' 
    GROUP BY p.prod_id , pgp.prod_grp_id 
    HAVING COUNT(p.prod_id) = 1 

)t 
where t.prod_id = #prods.prod_id 

-- view results 
select * from #prods 
0

Этот запрос поможет решить вашу фундаментальную проблему.

alter table prods 
drop column prod_grp_id 

Как вы описали, существует множество отношений между продуктами и группами. У вас также есть таблица prod_grp_prods для реализации этих отношений. Наличие поля группы id в вашей таблице продуктов - это просто, плохая идея.

Edit начинается здесь

Вот бинт решение

update p 
set prod_grp_id = pgp.prod_grp_id 
from prods p join prod_grp_prods pgp on p.prod_id = pgp.prod_id 
join (
select prod_id, count(*) records 
from prod_grp_prods 
group by prod_id 
having count(*) = 1) temp on temp.prod_id = p.prod_id 

Вам нужен другой запрос, чтобы свести на нет других записей.

+0

Это не шутка, но, к сожалению, я не в состоянии сделать такое изменение, так как есть много устаревшего материала, который будет затронут. –

0
UPDATE prods 
SET prod_grp_id = BS.prod_grp_id 
FROM (
      SELECT prods.prod_id, 
       pgp.prod_grp_id 

      FROM prods p 

       INNER JOIN prod_grp_prods pgp ON 
       prod.prod_id = pgp.prod_id 

       INNER JOIN prod_grps pg ON 
       pgp.prod_grp_id = pg.acct_grp_id 

      WHERE pg.prod_grp_mgr_nm LIKE '%LeadMGR%' 

      GROUP BY 
       p.prod_id, 
       pgp.prod_grp_id 

      HAVING COUNT(p.prod_id) = 1 
    ) BS 

    WHERE prods.prod_id = BS.prod_id 
+0

Хм, попробовал это, но получил «Msg 8120, уровень 16, состояние 1, строка 2 Столбец« prod_grp_prods.prod_grp_id »недопустим в списке выбора, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY. " сообщение. Я столкнулся с этой проблемой при попытке самостоятельно создать собственный оператор UPDATE. –

+0

Извините, что я только что сделал исправление. Попробуй это сейчас. – jcwrequests

Смежные вопросы