计算给定项目集(重量)所需的方框数

时间:2016-05-23 15:10:26

标签: sql sql-server sql-server-2008

我有一个ms-sql表,看起来像这样(weight = kg)。

sample table

我希望能够计算给定标识符所需的方框数和每箱重量。一个盒子最多可容纳30公斤。该标识符的所有项目都可以在一个框中混合。我仅限于sql(2008),但一切都可以使用(CTE,函数,StoredProcs等)。我尝试了不同的方法(CTE,功能),但我无法得到正确的结果。任何形式的帮助。

预期输出

选择标识符100001时

enter image description here

选择标识符100002时:

enter image description here

选择标识符100003时:

enter image description here

选择标识符100004时:

enter image description here

更新

样本表

import pickle

# Load model weights and metadata
weightFile = open('vgg16.pkl', 'rb')
d = pickle.load(weightFile, encoding='latin1')

示例数据

CREATE TABLE [dbo].[tblTest](
    [position] [int] NOT NULL,
    [item] [varchar](31) NOT NULL,
    [quantity] [money] NOT NULL,
    [weight] [money] NOT NULL,
    [identifier] [varchar](50) NOT NULL,
 CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED 
(
    [position] ASC,
    [identifier] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

1 个答案:

答案 0 :(得分:0)

这是一个选项:

请参阅此处的演示:http://rextester.com/THP2733

<强>设置:

create table tbl
(position integer, item integer, quantity integer, weight decimal(10,2), identifier integer);

insert into tbl
    select 1,  1, 4,  10, 100001 union all
    select 2,  2, 1,  15, 100001 union all
    select 1,  3, 3,  15, 100002 union all
    select 2,  4, 1,   5, 100002 union all
    select 3,  5, 3, 2.5, 100002 union all
    select 1,  6, 7,  25, 100003 union all
    select 1,  7, 1, 1.5, 100004 union all
    select 2,  8, 1, 2.5, 100004 union all
    select 3,  9, 3,   6, 100004 union all
    select 4, 10, 1,   1, 100004 ;

<强>查询:

with cte(position, item, quantity, weight, identifier, cntr)
as(select position, item, quantity, weight, identifier, quantity
   from tbl t1  
   union all   
   select t2.position, t2.item, t2.quantity, t2.weight, t2.identifier, cte.cntr - 1
   from tbl t2
   join cte 
     on t2.identifier = cte.identifier
    and t2.item = cte.item
    and cte.cntr > 1
)

select  
identifier,
sum(flg) over (partition by identifier order by item, cntr desc) package,
case when rolling_weight - lag(rolling_weight) over (partition by identifier order by cntr desc) is NULL then rolling_weight 
     else rolling_weight - lag(rolling_weight) over (partition by identifier order by cntr desc)
end weight
from 
(
    select temp1.*,
     case when rolling_weight % 30 = 0 then 1 
          when rolling_weight = total_weight then 1 
          when weight + lead(weight) over (partition by identifier order by cntr desc) > 30 then 1
          else 0 end as flg
    from
    (
        select 
          cte.*, 
          sum(weight) over (partition by identifier order by item, cntr desc) rolling_weight,
          sum(weight) over (partition by identifier) total_weight
        from cte
    ) temp1
) temp2
where flg = 1
order by identifier, package