很抱歉重新上传此问题,但我真的很想要答案。
请允许我再次提出这个问题,并希望您的支持。
问题是要找到合适的尺寸框,以便物流企业在运输时省钱。
我们有2个桌子,分别是盒子和产品。
盒子表包含每个盒子的每个ID和尺寸。“ w”表示宽度,“ d”表示深度,“ h”表示高度。为了方便起见,请假设我们只有3盒样品。
产品表还包括产品ID,尺寸。尺寸与箱形表的含义相同。“可放置”是指产品不仅可以以直立位置包装,还可以以可放置位置包装。例如,产品“ g”是一种易碎的瓶子,无法在盒子中放置水平位置。因此,这在可放置列中为“ n”。
这个问题需要在正确的尺寸框中查询每个产品ID。尺寸正确的包装箱意味着产品需要与最小空间的包装箱一起运输。
希望您的帮助。谢谢。
盒子:
BOX_SIZE | w ^ | d | H |
---|---|---|---|
小号 | 353 | 250 | 25 |
中号 | 450 | 350 | 160 |
大号 | 610 | 460 | 460 |
产品:
ID | w ^ | d | H | 可分层 |
---|---|---|---|---|
一种 | 350 | 250 | 25 | ÿ |
b | 450 | 250 | 160 | ÿ |
C | 510 | 450 | 450 | ÿ |
d | 350 | 250 | 25 | ÿ |
Ë | 550 | 350 | 160 | ÿ |
F | 410 | 400 | 430 | ñ |
G | 350 | 240 | 25 | ñ |
H | 450 | 350 | 160 | ñ |
一世 | 310 | 360 | 430 | ñ |
Ĵ | 500 | 500 | 600 | ÿ |
预期产量:
ID | BOX_SIZE |
---|---|
一种 | 小号 |
b | 中号 |
... | .... |
... | .... |
... | .... |
G | 小号 |
H | 中号 |
一世 | 大号 |
Ĵ | 无法使用 |
创建和填充用于测试的表的语句:
create table boxes
( box_size char(1) primary key
, w number not null
, d number not null
, h number not null
)
;
insert into boxes (box_size, w, d, h) values ('S', 353, 250, 25);
insert into boxes (box_size, w, d, h) values ('M', 450, 350, 160);
insert into boxes (box_size, w, d, h) values ('L', 610, 460, 460);
create table products
( id varchar2(10) primary key
, w number not null
, d number not null
, h number not null
, layable char(1) check(layable in ('y', 'n'))
)
;
insert into products (id, w, d, h, layable) values ('a', 350, 250, 25, 'y');
insert into products (id, w, d, h, layable) values ('b', 450, 250, 160, 'y');
insert into products (id, w, d, h, layable) values ('c', 510, 450, 450, 'y');
insert into products (id, w, d, h, layable) values ('d', 350, 250, 25, 'y');
insert into products (id, w, d, h, layable) values ('e', 550, 350, 160, 'y');
insert into products (id, w, d, h, layable) values ('f', 410, 400, 430, 'n');
insert into products (id, w, d, h, layable) values ('g', 350, 240, 25, 'n');
insert into products (id, w, d, h, layable) values ('h', 450, 350, 160, 'n');
insert into products (id, w, d, h, layable) values ('i', 310, 360, 430, 'n');
insert into products (id, w, d, h, layable) values ('j', 500, 500, 600, 'y');
commit;
关键当然是两个表之间的联接。为了帮助理解,我将首先单独显示它,而不是显示完整的查询。对于每个项目,我们找到了可以容纳该项目的所有盒子尺寸。
在所有情况下,如果产品高度<=盒子高度,并且其他两个尺寸符合任一排列方式,则匹配是可能的(产品始终可以旋转以适合盒子,无论它们是否可放置)。
仅对于可放置产品,我们允许将产品在所有三个维度上旋转以将其放入盒子中。这意味着,仅对于可放置产品,我们可以将产品宽度或深度与盒子高度进行比较,并将产品的其余两个尺寸与盒子宽度和深度进行比较。
一旦我们理解了我刚刚说的话(就像我们不用电脑,用铅笔在纸上就能做到的那样),代码转换几乎就是自动的:
select p.id, b.box_size
from products p left outer join boxes b
on
p.h <= b.h and least (p.w, p.d) <= least (b.w, b.d)
and greatest(p.w, p.d) <= greatest(b.w, b.d)
or
p.layable = 'y'
and
( p.w <= b.h and least (p.h, p.d) <= least (b.w, b.d)
and greatest(p.h, p.d) <= greatest(b.w, b.d)
or
p.d <= b.h and least (p.w, p.h) <= least (b.w, b.d)
and greatest(p.w, p.h) <= greatest(b.w, b.d)
)
;
输出:
ID BOX_SIZE
--- --------
a S
a M
a L
b M
b L
c L
d S
d M
d L
e L
f L
g S
g M
g L
h M
h L
i L
j
对于每种产品,我们发现了所有可行的尺寸。
注意查询中的外部联接,以包括不适合任何盒子大小的产品;product的情况就是这样j
,它出现在输出的末尾。请注意,我null
用作“不可用”的标记-“不可用”一词在简单使用时不会增加任何有价值的信息null
。
下一步是简单的汇总-对于每种产品,找到最小的尺寸。最好的工具是FIRST
聚合函数(如下所示)。我们必须按盒子尺寸订购;由于大小为S,M,L(偶然偶然按相反的字母顺序排列),因此我使用该decode()
函数将1分配给S,将2分配给M,将3分配给L。聚合查询会找到有效的“第一个”大小每个产品。
这里重要的是,即使不是所有三个维度都按升序排列,查询也可以轻松地推广为任意数量的“框大小”。(您也可以使用只有一个尺寸很大而其他尺寸很小的盒子,等等)。您可以按包装盒体积排序,也可以在包装盒表中存储优先顺序,这与我在使用该decode()
函数的查询中所做的等同。
最后,查询和输出如下所示。请注意,如果您确实需要它,我会nvl()
在select
子句中使用它来生成'not available'
最后一项(我对此表示怀疑,但这不是我的业务问题。)
select p.id,
nvl( min(b.box_size) keep (dense_rank first
order by decode(b.box_size, 'S', 1, 'M', 2, 'L', 3))
, 'not available') as box_size
from products p left outer join boxes b
on
p.h <= b.h and least (p.w, p.d) <= least (b.w, b.d)
and greatest(p.w, p.d) <= greatest(b.w, b.d)
or
p.layable = 'y'
and
( p.w <= b.h and least (p.h, p.d) <= least (b.w, b.d)
and greatest(p.h, p.d) <= greatest(b.w, b.d)
or
p.d <= b.h and least (p.w, p.h) <= least (b.w, b.d)
and greatest(p.w, p.h) <= greatest(b.w, b.d)
)
group by p.id
;
ID BOX_SIZE
--- --------
a S
b M
c L
d S
e L
f L
g S
h M
i L
j not available
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句