T-SQL - обновить таблицу с данными из той же таблицы - неоднозначная таблица - PullRequest
0 голосов
/ 28 июня 2018

У меня проблемы с пониманием, почему этот запрос не работает. Я получаю сообщение

Таблица '#PriceChanges' неоднозначна

Первое упоминание о #PriceChanges подчеркнуто

UPDATE #PriceChanges
SET MaxQty = MIN(ISNULL(PT.MinQty, 100000000))
FROM #PriceChanges P
LEFT JOIN #PriceChanges PT ON P.ChangeType = PT.ChangeType
                           AND P.ItemNo = PT.ItemNo
                           AND P.MinQty < PT.MinQty

Итак, я пытаюсь установить максимальное количество данной строки равным следующему количеству MIN, найденному в той же таблице. Если ничего не найдено, просто сделайте это смехотворно большим числом (100 000 000)

Конечный результат должен выглядеть примерно так

MinQty  MaxQty
-----------------
   0          20
  20          50
  50         100
 100   100000000

Любая помощь будет принята с благодарностью!

Спасибо

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Создание промежуточной таблицы сработало, я все еще удивляюсь, почему все это не может быть помещено в одно обновление

SELECT P.ChangeType, P.ItemNo, P.MinQty, MIN(PT.MinQty) AS MaxQty
INTO #MaxQty
FROM #PriceChanges P
LEFT JOIN #PriceChanges PT
    ON P.ChangeType = PT.ChangeType
    AND P.ItemNo = PT.ItemNo
    AND P.MinQty < PT.MinQty
GROUP BY P.ChangeType, P.ItemNo, P.MinQty

UPDATE #PriceChanges 
SET MaxQty = ISNULL(PM.MaxQty, 100000000)
FROM #PriceChanges P
LEFT JOIN #MaxQty PM
    ON P.ChangeType = PM.ChangeType
    AND P.ItemNo = PM.ItemNo
    AND P.MinQty = PM.MinQty
0 голосов
/ 28 июня 2018

Неопределенность возникает из-за того, что предложение FROM в UPDATE дважды ссылается на таблицу #PriceChanges, поэтому у SQL Server нет возможности узнать, какие из двух вы собираетесь обновить. Чтобы устранить неоднозначность, вместо записи UPDATE #PriceChanges используйте UPDATE P или UPDATE PT. Вот тривиальный пример:

create table #Test (id int, datum char(1));
insert #Test values (1, ' '), (2, ' ');

-- ERROR: The table '#Test' is ambiguous.
update #Test set datum = 'X' from #Test T1 inner join #Test T2 on T1.id = T2.id + 1;

-- CORRECT: Use the appropriate table alias to indicate which instance of #Test you want to update.
update T1 set datum = 'X' from #Test T1 inner join #Test T2 on T1.id = T2.id + 1;
0 голосов
/ 28 июня 2018

Не вижу смысла для ISNULL(PT.MinQty, 100000000). MIN() игнорирует NULL значения. И вам не нужно самостоятельное присоединение. Работает обновляемый CTE или подзапрос:

UPDATE pc
    SET MaxQty = min_minqty
FROM (SELECT pc.*, MIN(pc.MinQty) OVER (PARTITION BY ItemNo, ChangeType) as min_minqty
      FROM #PriceChanges pc 
     ) pc
WHERE pc.MaxQty <> min_minqty;

EDIT:

Похоже, вы хотите:

with pc as (
      select pc.*,
             lead(pc.MinQty) over (order by pc.MinQty) as next_MinQty
      from #PriceChanges pc
     )
update pc
    set MaxQty = next_MinQty;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...