在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。
MS-SQL 根据实际所需规格table去比对另一个库存table取浪费最少的数据
http://bbs.csdn.net/topics/390619048
情境描述:根据表A里的物料去比对表B,然后表A根据A1括号里两个尺寸浪费最少来将A1替换成最省的物料。
表A用量需求表:Table A
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(900*110)
1 ls002-(200*300)
....
表B库存物料表: B1没有重复,可以当作ID来使用 Table B:
B1(库存物料) B2(规格1) B3(规格2)
----------------------------------------------
ls001-(700*200) 700 200
ls001-(910*140) 910 140
ls001-(920*120) 920 120
... ... ...
ls002-(100*200) 100 200
ls002-(200*350) 200 350
ls002-(220*320) 220 320
...
原理是:ls001取(920*120)的话浪费分别是左边920-900=20,右边120-110=10,总共浪费是30, 是ls001库存规格(700*200),(910*140),(920*120)里浪费最少的,ls002同理。
最后A1字段被替换后的效果如下:
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(920*120)
1 ls002-(220*320)
...
各位有什么好的方案或者算法可分享来学习借鉴一下 ^_^
我的解法:
-
drop
table a
-
drop
table b
-
-
create
table a (a0
int,a1
varchar(
100),a2
int,a3
int)
-
-
insert
into a
-
SELECT
0,
'ls001-(900*110)',
900,
110
UNION ALL
-
SELECT
1,
'ls002-(200*300)',
200,
300
-
-
-
create
table b (B1
varchar(
100),B2
int,B3
int)
-
-
insert
into b
-
SELECT
'ls001-(700*200)',
700,
200
UNION ALL
-
SELECT
'ls001-(910*140)',
910,
140
UNION ALL
-
SELECT
'ls001-(920*120)',
920,
120
UNION ALL
-
SELECT
'ls002-(100*200)',
100,
200
UNION ALL
-
SELECT
'ls002-(200*350)',
200,
350
UNION ALL
-
SELECT
'ls002-(220*320)',
220,
320
-
-
-
;with t
-
as
-
(
-
select a0,a1,
-
substring(a1,
1,
charindex(
'-',a1)
-1)
as b1,
-
a2,a3
-
--substring(a1,charindex('(',a1)+1, charindex('*',a1)-charindex('(',a1)-1) as b2,
-
--substring(a1,charindex('*',a1)+1, charindex(')',a1)-charindex('*',a1)-1) as b3
-
-
from a
-
),
-
-
tt
-
as
-
(
-
select t.a0,
-
t.a1,
-
b.b1,
-
row_number()
over(
partition
by t.a1
-
order
by
abs(t.a2-b.b2) +
abs(t.a3 - b.b3))
as
rownum
-
from b
-
inner
join t
-
on b.b1
like t.b1 +
'%'
-
)
-
-
select a0,b1
as a1
-
from tt
-
where
rownum =
1
-
/*
-
a0 a1
-
0 ls001-(920*120)
-
1 ls002-(220*320)
-
*/