SQL переупорядочение приоритета построчно

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

Моя таблица SQL имеет 3 поля, которые влияют на мою проблему: «Приоритет» как реальное, Start_Date как datetime и Furnace_Name как varchar (10). Когда пользователь добавляет элементы в таблицу (через приложение VB.net для Windows), он (и) указывает приоритет для заданной даты начала.

Если Item1 является Приоритетом 1 в указанной Печи , то Item2 в той же Печи , может быть Приоритетом 2, и ему будет присвоено Start_Date после Item 1.

Но если Item2 присвоен приоритет 0.5 (или любое число меньше приоритета Item1), то его Start_Date будет раньше Start_Date элемента 1. Примечание. Пользователь может указать прим. 3,75 или любое другое число. Из-за бизнес-правил работа с PR 0,5 может быть продвинута и завершена после работы с более высоким номером приоритета в той же печи.

После добавления каждого элемента я хочу просмотреть список элементов и обновить все приоритеты, чтобы они стали целыми числами, начиная с самой ранней даты Start_Date с приоритетом = 1, затем 2, 3 и т. Д. Но в первый раз, когда я разместил сообщение В этом вопросе я не упомянул, что Приоритеты перенумерации происходят внутри каждой Печи, так что каждая Печь может иметь Prioirty 1, 2 и т. д.

Кроме того, указанная печь может иметь 1: n элементов с одинаковым приоритетом. После того, как я перенумерую эти Приоритеты в целые числа, элементы, которые начинаются с того же Приоритета, должны иметь тот же Приоритет.

Читатель предложил:

Update Table 
Set Priority = 
    (Select Count(*) 
     From table
     Where Start_Date <= T.Start_Date)   
     From Table T   
Where Start_Date > getDate()

Я улучшил это, чтобы:

Update tblTable
Set      Priority = 
 (Select Count(*) 
 From tblTable
 Where Start_Date <= T.Start_Date and
 Start_Date  >= @CutoffDate 
 and Furnace_Name = T.Furnace_Name
 )   
From tblTable T

Но это не совсем работает, потому что Приоритеты в печи не начинаются с 1. Может ли кто-нибудь объяснить мне лучший способ сделать это или подойти к проблеме?

Вот некоторые тестовые данные:

Sch_ID Furnace Start_Date Приоритет Желаемый приоритет после повторного заказа 372 1335 9/9/09 8:00 AM 1 1 380 1335 11/9/09 7:00 AM 1 1 314 1335 9.09.09 10:30 AM 2 2 324 1335 09.09.09 10:00 AM 2 2 235 1335 09.11.09 16:00 0.5 3 234 1335 09.11.09 16:00 0.5 3

403 1510 11.09.09 11:30 AM 2 2 404 1510 11.09.09 11:30 AM 2 2 402 1510 09.09.09 8:30 AM 2 2 389 1510 11.09.09 7:30 AM 1 1 390 1510 11.09.09 7:30 AM 1 1 388 1510 09.09.09 7:00 AM 1 1 374 1510 09.09.09 18:30 3.5 4 383 1510 11.09.09 5: 30:00 3.5 4 385 1510 9.09.09 15:30 3 3 386 1510 9.09.09 13:30 3 3

Спасибо.

PS

Причина, по которой мне нужно в первую очередь изменить нумерацию Приоритета Работы, заключается в том, что после применения бизнес-правил, относящихся к планированию Заданий, возможно (хотя и редко), что их Приоритеты выходят из числового порядка. Например, наличие дублирования в другой печи может отодвинуть время начала текущей работы назад, заставив его быть позже в течение дня, чем задание с более высоким номером PR (и, следовательно, с более низким приоритетом).

Так как пользователь указывает относительную важность работы в печи, указав PR, необходимо, чтобы мы перенумеровали приоритеты после добавления каждой работы. Ситуация, описанная выше, когда задание с PR 2 находится между двумя заданиями с PR 1, не может возникнуть, хотя 2 или более заданий с одинаковым приоритетом будут запланированы на одно и то же время.

Я ценю помощь, которую вы предложили. Можете ли вы сделать последний шаг?

Спасибо.

9.11.2009 15:01:42
Тогда нет последнего шага, мой запрос должен работать как есть. На данный момент те же приоритеты остаются прежними. Drвсегда равно Pr. Не могли бы вы опубликовать пример данных, которые он не хранит?
Quassnoi 10.11.2009 14:50:23
Извините за задержку, чтобы вернуться к вам. Многие структуры, которые вы использовали в приведенном выше запросе, мне незнакомы, поэтому я пытаюсь понять, что вы сделали и как. В частности, я никогда не видел Dense_Rank или Partition By или оператора With в SQL. Вы сказали: «Это зависит от того факта, что исходные приоритеты упорядочены так же, как StartDates». Но, на самом деле, это не может быть правдой, и именно поэтому мне нужно менять Приороты, так что это становится правдой, после каждого запланированного действия.
Melody Friedenthal 12.11.2009 14:49:14
3 ОТВЕТА

Я думаю, что это плохая идея иметь поле, которое устанавливается как пользователем, так и полуавтоматическим алгоритмом приложением / базой данных. Разве вы не можете просто заказать на основе Start_Dateи за, Priorityкогда вы selectиз таблицы?

1
9.11.2009 15:11:05
WITH    rows AS
        (
        SELECT  tt.*, DENSE_RANK() OVER (PARTITION BY Furnace_Name ORDER BY Priority) AS dr
        FROM    tblTable tt
        )
UPDATE  rows
SET     Priority = dr

Обновление 2:

Попробуй это:

WITH    data (Sch_ID, Furnace, Start_Date, Priority, Pr) AS
        (
        SELECT 372, 1335, CAST('11/9/09 8:00 AM' AS DATETIME), 1, 1
        UNION ALL
        SELECT 380, 1335, '11/9/09 7:00 AM', 1, 1
        UNION ALL
        SELECT 314, 1335, '11/9/09 10:30 AM', 2, 2
        UNION ALL
        SELECT 324, 1335, '11/9/09 10:00 AM', 2, 2
        UNION ALL
        SELECT 235, 1335, '11/9/09 4:00 PM', 0.5, 3
        UNION ALL
        SELECT 234, 1335, '11/9/09 4:00 PM', 0.5, 3
        UNION ALL
        SELECT 403, 1510, '11/9/09 11:30 AM', 2, 2
        UNION ALL
        SELECT 404, 1510, '11/9/09 11:30 AM', 2, 2
        UNION ALL
        SELECT 402, 1510, '11/9/09 8:30 AM', 2, 2
        UNION ALL
        SELECT 389, 1510, '11/9/09 7:30 AM', 1, 1
        UNION ALL
        SELECT 390, 1510, '11/9/09 7:30 AM', 1, 1
        UNION ALL
        SELECT 388, 1510, '11/9/09 7:00 AM', 1, 1
        UNION ALL
        SELECT 374, 1510, '11/9/09 6:30 PM', 3.5, 4
        UNION ALL
        SELECT 383, 1510, '11/9/09 5:30 PM', 3.5, 4
        UNION ALL
        SELECT 385, 1510, '11/9/09 3:30 PM', 3, 3
        UNION ALL
        SELECT 386, 1510, '11/9/09 1:30 PM', 3, 3
        ),
        ranks AS
        (
        SELECT  *, DENSE_RANK() OVER (PARTITION BY Furnace ORDER BY CASE WHEN Priority = 0.5 THEN 1 ELSE 0 END, Priority) AS Dr
        FROM    data
        )
SELECT  *
FROM    Ranks
ORDER BY
        Furnace, Start_Date

Это зависит от того факта, что исходные приоритеты упорядочены так же, как и StartDates.

Вы должны решить, что произойдет, если они не будут. Скажите, как эти данные будут упорядочены?

Date   Priority 
07:00  1
08:00  2
09:00  1
10:00  2
2
9.11.2009 21:58:06
Это очень интересный запрос. Я сделал копию своей таблицы и попробовал ее, но добавил предложение where, чтобы затронуть только те строки с Start_Date больше 7:00 AM сегодня. Строки с приоритетом = 0,5 были изменены на Приоритет 1 для одной печи. Следующая группа строк начиналась с приоритета 3 (не было строк с приоритетом 2) и оставалась на уровне 3, но я хотел, чтобы их приоритет был перенумерован в 2. Спасибо за этот код. Если вы можете внести дополнительные улучшения или предложения, я был бы признателен.
Melody Friedenthal 9.11.2009 19:36:53
Не могли бы вы опубликовать пример данных для тестирования?
Quassnoi 9.11.2009 19:40:34
Пример тестовых данных: Sch_ID Furnace Start_Date Priority Pr после повторного заказа 372 1335 9/9/09 8:00 AM 1 1 380 1335 11/9/09 7:00 AM 1 1 314 1335 9/9/09 10:30 AM 2 2 324 1335 09.11.09 10:00 AM 2 2 235 1335 09.09.09 16:00 0.5 3 234 1335 09.11.09 16:00 0.5 3 403 1510 11.09.09 11: 30:00 2 2 404 1510 11.09.09 11:30 AM 2 2 402 1510 09.09.09 8:30 AM 2 2 389 1510 11.09.09 7:30 1 1 390 1510 11.09.09 7:30 AM 1 1 388 1510 09.11.09 7:00 AM 1 1 374 1510 11.09.09 18:30 3,5 4 383 1510 11 сентября 2009 г. 3,5 4 385 1510 11/9 / 09 15:30 3 3 386 1510 9.09.09 13:30 3 3
Melody Friedenthal 9.11.2009 20:55:57
Просто добавьте это к оригинальному сообщению.
Quassnoi 9.11.2009 21:10:52
Почти. Упорядочение выполняется по Start_Date, а не по оригинальному приоритету. Таким образом, те, которые начинались как Приоритет .5 в тестовых данных, запланированы позже, чем те, которые имеют Приоритет 1 и те, которые имеют Приоритет 2. Таким образом, они должны стать приоритетом 3. Вы переназначаете их на PR 1.
Melody Friedenthal 9.11.2009 21:45:03

Мне кажется, что главной проблемой здесь является базовая модель, которая усложняет эту задачу. Если бы вы рассмотрели изменение модели, большинство ваших проблем исчезло бы, например:

furnace_model_01
Я знаю, что это не совсем то, что вы просили, но в долгосрочной перспективе ...

ОБНОВЛЕНИЕ ПОСЛЕ КОММЕНТАРИИ :
Это должно позволить вам указать, кто запланировал что, когда и где.

furnace_model_02

2
13.08.2016 16:35:23
Пользователь должен видеть Приоритеты в графическом интерфейсе приложения VB. Из-за бизнес-логики планирования я мог получить задание с приоритетом 0.5 после задания с приоритетом 4. Это нелогично, поэтому, когда эта операция будет завершена, мне нужно будет перенумеровать все задания во всех задействованных печах (и для любого при заданной операции планирования могут быть затронуты 1 или 2 печи. Например, мы можем перенести работу из одной печи в другую, операцию, которая затрагивает 2 печи. Я бы, конечно, рассмотрел бы изменение модели, если бы что-то еще имело смысл.
Melody Friedenthal 9.11.2009 19:24:07
В графическом интерфейсе вы можете отобразить AssignedPriority, позволить пользователю изменить это и затем сохранить его в RequestedPriority; затем вы запускаете второй проход по всей таблице, чтобы настроить AssignedProrities и установить StartTimes для каждого из них. В этой модели вы ничего не нумеруете, просто настраиваете Priorities и StartTime. В идеале вы даже ничего не удаляете, чтобы сохранить историю работы.
Damir Sudarevic 9.11.2009 20:25:40