Запрос CTE в SQL Server: выход, если в результате существует одна строка - PullRequest
0 голосов
/ 20 января 2019

Я пишу процедуру SQL Server для оптимизации среза баров.Я еще не нашел лучший метод.Похоже, запрос CTE, но я застрял.

Я пытаюсь написать хранимую процедуру для оптимизации среза баров.Для моего теста я должен разрезать 18 кусков (3 из 1000 мм, 3 из 1500 мм, 3 из 2500 мм, 3 из 3500 мм, 3 из 4500 мм и 3 из 6000 мм), и у меня есть 3 размера стержней (5500 мм, 7000 мм и 8500 мм).

После этого я генерирую каждую комбинацию баров с любыми разрезами, насколько это возможно.

Я пробовал с циклом while и временной таблицей, Это занимает у меня один час иполовина.Но я думаю, что могу добиться большего успеха с запросом CTE ...

Теперь я должен сгенерировать каждую комбинацию из множества баров, чтобы получить мои 18 срезов.Я сделал еще один запрос CTE, но я не нашел способа остановить рекурсивность, когда хотя бы одна комбинация имеет все сокращения.Итак, моя просьба найти более 150 миллионов комбинаций с 8,9,10,11 ... барами.И он пробует каждую петлю с 18 барами.Я хочу, чтобы он остановился с 8 барами (я знаю, что это наименьшее количество баров, необходимое для моих сокращений).И это занимает более двух дней!

У меня есть 2 временные таблицы с моей комбинацией баров (#COMBI_BARRE) со следующей структурой: ID_ART: идентификатор для статьи, COLOR, CUT_COMBI: varchar, конкат, идентифицирующий вырезанный IDкомбинации столбцов: 1-2-3-4 ..., NB_CUTSan целое число, чтобы получить количество срезов в баре, FIRST_CUT меньший ID среза бара.

У меня есть другая временная таблица #DET_BARс подробными сведениями о моих срезах, с 2 столбцами: ID_COMBI_BAR - идентификатор комбинации столбцов и ID_CUT_STR - идентификатор среза в varchar (чтобы избежать приведения или преобразования в CTE для повышения производительности).

Я сохраняю результат в таблицевызовите Combi, с помощью ID_ART, COLOR, столбца varchar Combi, который объединяет идентификатор комбинации столбцов (1-2-3-4 ...), столбца varchar COMBI_CUT, который объединяет ID_CUT (1-2-3-4)-5 ...), NB_BAR - количество баров в комбинации, NB_CUTS: количество срезов в комбинации, MAX_CUTS - общее количество срезов, необходимых для моей статьи и цвета.

Как это делаетсяодин цикл наКроме того, я попытался добавить предложение о существовании, чтобы остановить рекурсивность, когда число циклов имеет хотя бы одну комбинацию со всеми моими срезами.Я знаю, что я не должен сокращать 10 баров, если я могу сделать это с 8. Но я получаю ошибку «рекурсивная таблица имеет множественные ссылки».

Как я могу сделать свой запрос и избежать каждого цикла?

;WITH Combi (ID_ART, COLOR, COMBI, COMBI_CUT, NB_BAR, NB_CUTS, MAX_CUTS)
AS
( SELECT C.ID_ART, 
        C.COLOR,
      '-' + ID_COMBI_BAR_STR + '-',
         '-' + C.CUT_COMBI + '-',
         1,
         C.NB_CUTS,
         ISNULL(MAXI.CUT_NUM,0)
FROM #COMBI_BARRE C with(nolock)
outer apply (select top 1 D.CUT_NUM
             from #DEBITS D
             where D.ID_ART = C.ID_ART
             and D.COLOR= C.COLOR
             order by D.NUM_OCC_DEB desc) MAXI
WHERE C.FIRST_CUT = 1
UNION ALL
SELECT C.ID_ART, 
             C.COLOR, 
             Combi.COMBI  + ID_COMBI_BAR_STR + '-',
             Combi.COMBI_CUT+ C.CUT_COMBI + '-',
             Combi.NB_BAR+ 1,
             Combi.NB_CUTS+ C.NB_CUTS,
             Combi.MAX_CUTS
  FROM #COMBI_BARRE C with(nolock)
  INNER JOIN Combi  on C.ID_ART = Combi.ID_ART
                          and C.COLOR= Combi.COLOR
  where C.FIRST_CUT > Combi.NB_BAR
  and Combi.NB_CUTS+ C.NB_CUTS<= Combi.MAX_CUTS
  and NOT EXISTS(select * from #DET_BAR D with(nolock)
                           where D.ID_COMBI_BAR = C.ID_COMBI_BAR
                           and PATINDEX(D.ID_CUT_STR, Combi.COMBI_CUT) > 0)
 and NOT EXISTS(select top 1 * from Combi Combi2 where Combi2.ID_ART = C.ID_ART and Combi2.COLOR = C.COLOR and Combi2.NB_CUTS = Combi2.MAX_CUTS)
)
select * from Combi 

1 Ответ

0 голосов
/ 20 января 2019

Это вариант проблемы упаковки бункера.Этот поисковый термин может помочь вам в правильном направлении.

Кроме того, вы можете перейти на мою страницу Bin Packing , которая дает несколько подходов к более упрощенной версии вашей проблемы.

Небольшое предупреждение: связанные статьи не используют (рекурсивный) CTE, поэтому они не будут отвечать на ваш конкретный вопрос CTE.

...