如何确定所需最少盒数的最佳包装?

时间:2019-01-19 15:52:21

标签: tsql while-loop common-table-expression sql-server-2016

我试图找出是否有更好的方法可以执行此操作...下面的代码有效,但是我必须在double while循环内执行几个查询,对我来说,这似乎并没有是最好的方法。

问题:我有很多批次,每批次中有不同数量的单位。我需要确定每个盒子最多包装50个单位所需的盒子总数,而不必将很多东西分成两个不同的盒子。我需要一个包含Box ID,批号和该批中单位数的列表。如果该框中所有批次之间的单元总数少于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

感谢您的任何建议, 无限

0 个答案:

没有答案