Как определить наилучшую упаковку для наименьшего количества необходимых коробок? - PullRequest
0 голосов
/ 19 января 2019

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

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

IF OBJECT_ID('tempdb..#temp') IS NOT NULL DROP TABLE #temp

CREATE TABLE #temp (
   SYSID BIGINT NOT NULL IDENTITY(1,1),
   LOT_NUMBER NVARCHAR(100) NOT NULL,
   UNIT_COUNT BIGINT NOT NULL,
   BOX_ID BIGINT NULL,
   PROCESSED BIT NULL
)

INSERT INTO #temp
(
   LOT_NUMBER,
   UNIT_COUNT
)
VALUES
('0111590',2),
('0111944',18),
('0111978',5),
('0111982',15),
('0111985',15),
('0111995',14),
('0111996',34),
('0111997',29),
('0111998',16),
('0111999',17),
('0112001',26),
('0112002',29),
('0112004',17)


DECLARE @BOX_ID BIGINT
DECLARE @SYSID1 BIGINT
DECLARE @SYSID2 BIGINT
DECLARE @SYSID3 BIGINT
DECLARE @UNIT_COUNT BIGINT
SET NOCOUNT ON

SET @BOX_ID = 1

WHILE (SELECT COUNT(*) FROM #temp WHERE BOX_ID IS NULL) > 0
BEGIN
   SELECT TOP 1 @SYSID1 = t.SYSID, @UNIT_COUNT = 50 - t.UNIT_COUNT
   FROM #temp t
   WHERE BOX_ID IS NULL
   ORDER BY t.UNIT_COUNT DESC

   UPDATE t SET
      t.BOX_ID = @BOX_ID
   FROM #temp t
   WHERE SYSID = @SYSID1

   WHILE(SELECT COUNT(*) FROM #temp WHERE BOX_ID IS NULL AND PROCESSED IS NULL) > 0
   BEGIN
       SELECT TOP 1 @SYSID2 = t.SYSID
       FROM #temp t
       WHERE t.BOX_ID IS NULL
         AND t.PROCESSED IS NULL
       ORDER BY t.UNIT_COUNT desc

       SELECT TOP 1 @SYSID3 = t.SYSID, @UNIT_COUNT = @UNIT_COUNT - t.UNIT_COUNT
       FROM #temp t
       WHERE t.BOX_ID IS NULL
         AND t.UNIT_COUNT <= @UNIT_COUNT
       ORDER BY t.UNIT_COUNT desc

       UPDATE t SET
          t.BOX_ID = @BOX_ID
       FROM #temp t
       WHERE t.SYSID = @SYSID3

       UPDATE t SET
           t.PROCESSED = 1
       FROM #temp t
       WHERE SYSID = @SYSID2
   END

   INSERT INTO #temp
   (
       BOX_ID,
       LOT_NUMBER,
       UNIT_COUNT
   )
   SELECT @BOX_ID, 'DUMMY UNITS', @UNIT_COUNT
   WHERE @UNIT_COUNT > 0

   SELECT @BOX_ID = @BOX_ID + 1

   UPDATE t SET
      t.PROCESSED = NULL
   FROM #temp t
   WHERE BOX_ID IS NULL

END

SELECT 
  BOX_ID,
  LOT_NUMBER,
  UNIT_COUNT
FROM #temp 
ORDER BY BOX_ID,UNIT_COUNT desc

Выходэтого кода

BOX_ID  LOT_NUMBER     UNIT_COUNT
1       0111996        34
1       0111998        16
2       0111997        29
2       0111944        18
2       0111590        2
2       DUMMY UNITS    1
3       0112002        29
3       0111999        17
3       DUMMY UNITS    4
4       0112001        26
4       0112004        17
4       0111978        5
4       DUMMY UNITS    2
5       0111982        15
5       0111985        15
5       0111995        14
5       DUMMY UNITS    6

Спасибо за любые рекомендации, jlimited

...