Я хочу обновить строки таблицы в определенном порядке, как и следовало ожидать, если включить предложение ORDER BY, но SQL Server не поддерживает предложение ORDER BY в запросах UPDATE.
Я проверил этот вопрос, который предоставил хороший решение, но мой запрос немного сложнее, чем указанный там.
UPDATE TableA AS Parent
SET Parent.ColA = Parent.ColA + (SELECT TOP 1 Child.ColA
FROM TableA AS Child
WHERE Child.ParentColB = Parent.ColB
ORDER BY Child.Priority)
ORDER BY Parent.Depth DESC;
Итак, я надеюсь, вы заметите, что одна таблица (TableA
) содержит иерархию строк, в которой одна строка может быть родительской или дочерней для любой другой строки. Строки должны быть обновлены в порядке от самого глубокого дочернего элемента до корневого родителя. Это связано с тем, что TableA.ColA
должен содержать актуальную конкатенацию собственного текущего значения со значениями его дочерних элементов (я понимаю, что этот запрос объединяет только один дочерний элемент, но это ради простоты — цель примера в этот вопрос не требует дополнительной детализации), поэтому запрос должен обновляться снизу вверх.
Решение, предложенное в вопросе, который я отметил выше, выглядит следующим образом:
UPDATE messages
SET status=10
WHERE ID in (SELECT TOP (10) Id
FROM Table
WHERE status=0
ORDER BY priority DESC
);
Причина, по которой я не думаю, что смогу использовать это решение, заключается в том, что я ссылаюсь на значения столбцов из родительской таблицы внутри своего подзапроса (см. WHERE Child.ParentColB = Parent.ColB
), и я не думаю, что два родственных подзапроса будут иметь доступ к данным друг друга.
Пока что я нашел только один способ объединить это предложенное решение с моей текущей проблемой, и я думаю, что он не работает.
UPDATE TableA AS Parent
SET Parent.ColA = Parent.ColA + (SELECT TOP 1 Child.ColA
FROM TableA AS Child
WHERE Child.ParentColB = Parent.ColB
ORDER BY Child.Priority)
WHERE Parent.Id IN (SELECT Id
FROM TableA
ORDER BY Parent.Depth DESC);
Подзапрос WHERE..IN
на самом деле не вернет подмножество строк, он просто вернет полный список идентификаторов в нужном мне порядке. Однако (я не знаю точно - скажите, пожалуйста, если я ошибаюсь) я думаю, что предложение WHERE..IN
не будет заботиться о порядке идентификаторов в круглых скобках - оно просто проверит идентификатор строки, которую он в данный момент хочет обновить, чтобы увидеть, находится ли он в этом списке (а они все есть) в любом порядке, в котором он уже пытается обновить... Это было бы просто пустой тратой циклов, потому что это ничего не изменит.
Итак, в заключение, я осмотрелся и не могу найти способ обновления в указанном порядке (и включил причину обновления в этом порядке, потому что я уверен, что в противном случае получил бы очень полезные ответы «почему?»), и теперь я нажимаю на Stack Overflow, чтобы узнать, знает ли кто-нибудь из вас, гуру, которые знают о SQL больше, чем я (что не говорит многого) о эффективный способ сделать это. Особенно важно, что я использую только один запрос для выполнения этого действия.
Длинный вопрос, но я хотел покрыть свои основы и дать вам, ребята, как можно больше информации, чтобы питаться ею. :)
Есть предположения?