2014-07-01 3 views
0

У меня есть таблица продуктов с колонками (Name, ParentID, Order). У меня есть инструкция insert, в которой хранятся вставленные дочерние продукты. После вставки мне нужно обновить заказ,Обновление заказа на продукт не работает

У меня есть следующий SQL,

UPDATE Products 
SET  [Order] = (SELECT ISNULL(MAX([Order]), 0) + 1 FROM Products WHERE ParentID = CP.ParentID) 
FROM Products P 
     INNER JOIN #InsertedChildProduct CP ON (CP.ID = P.ID) 

Проблема заключается в том, что я обновляя заказ продуктов, которые только что вставил, но [Заказ] не работает , Если у меня есть,

Products 
-------- 
ParentID Order 
---------------- 
1   1 
1   2 

и пусть говорят, я вставил 2 ребенка продуктов, то таблица должна быть,

Products 
-------- 
ParentID Order 
---------------- 
1   1 
1   2 
1   3 
1   4 

Но я вижу,

Products 
-------- 
ParentID Order 
---------------- 
1   1 
1   2 
1   3 
1   3 
+1

это просто выполняется обновление за один проход, поэтому MAX + 1 будет таким же независимо от того, сколько строк вы обновляете. – Tanner

+0

@Tanner - любое решение. – user960567

+0

Мышление ... tick tock tick tock :-) – Tanner

ответ

0

Попробуйте, как это вместо того, вам необходимо до MAX() первый внутренний запрос

UPDATE P 
SET  [Order] = X.newval 
FROM Products P 
JOIN 
(
SELECT ID, (ISNULL(MAX([Order]), 0) + 1) as newval 
FROM Products P 
JOIN #InsertedChildProduct ip 
on P.ParentID = ip.ParentID 
group by ID 
) X 
ON X.ID = P.ID 
+0

Я получаю 'Агрегат может не отображаются в заданном списке инструкции UPDATE. ' – user960567

+0

Вам нужно получить' max' во внутреннем запросе. См. Отредактированный ответ. – Rahul

0

Вы можете попробовать это, взятое из ответов на here:

declare @MaxNumber int 
set @MaxNumber = 0 
UPDATE Products 
SET [Order] = @MaxNumber, @MaxNumber = (SELECT ISNULL(MAX([Order]), 0) 
             FROM Products 
             WHERE ParentID = CP.ParentID) + 1 
FROM Products P 
     INNER JOIN #InsertedChildProduct CP ON (CP.ID = P.ID) 
+0

Проблема заключается в том, что '# InsertedChildProduct' включает в себя разных родителей. – user960567

+0

@ user960567 так и есть ваша статья where и join, не учитывающая это? – Tanner

+0

текущая sql - упрощенная версия – user960567

0

Мысль об этом кучу разных способов, и не может понять, как это будет работать без наведения порядка на обоих наборах данных, даже если произвольно. Вот один из способов сделать это (Fiddle - убедитесь, что для построения схемы первого, а затем запустить код): http://www.sqlfiddle.com/#!3/d34df/3)

WITH cteRN_c 
AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS RN_c, 
      ID 
    FROM #InsertedChildProduct 
), 
cteRN_p 
AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ParentID ORDER BY [Order]) AS RN_p, 
      ParentID, 
      [Order] 
    FROM Products 
    WHERE [Order] IS NULL 
) 

UPDATE p 
SET  [Order] = (SELECT ISNULL(MAX([ORDER]), 0) FROM Products WHERE ParentID = p.ParentID) + c.RN_c     
FROM  cteRN_p p INNER JOIN cteRN_c c 
      ON p.ParentID = c.ID AND 
      p.RN_p = c.RN_c; 

Мы навести порядок, добавляя произвольные числа строк как к набору температуры таблицы и родительского набора , через ROW_NUMBER в CTE. С этого момента речь идет только о подключении CTE к правильным точкам данных и запуске обновлений для родительского CTE. Конечно, произвольно, какой ребенок будет пронумерован в каком порядке, но, по крайней мере, это произойдет.

Редактировать: Забыл ISNULL в MAX-части запроса - в случае отсутствия детей. Обновлен скрипт.

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