In the forum, I met a lot more difficult sql problem, although they can be resolved, but found a few days later, they can not remember, forget the solution of.
So, I feel the need to be recorded, so that after the encounter this problem again, and get answers from the idea.
MS-SQL table based on the actual inventory required specification data table to take minimal waste other than
http://bbs.csdn.net/topics/390619048
Context description: Table A material according to comparison tables B, Table A and A1 happened to be replaced according to the material of least two dimensions A1 brackets waste.
Table A table amount of demand: the Table A
A0 (self-growth ID) A1 (item number)
-------------------------------
ls001- 0 (900 * 110)
. 1 ls002- (200 is 300 *)
....
table B table Stock material: B1 does not repeat, can be used as ID B the table:
Bl (stock material) B2 (size 1) B3 (size 2)
----------------------------------------------
ls001- (200 is 700 *) 700 200 is
ls001- (910 * 140) 910 140
ls001- (920. * 120) 920. 120
... ... ...
ls002- (200 is 100 *) 100 200 is
ls002- (* 200 is 350) 350 200 is
ls002- (220 * 320.) 320. 220
...
The principle is: ls001 taken (920 120 *) are left, then waste 920-900 = 20, 120-110 = 10 to the right, a total of 30 to waste, is LS001 stock standard (700 * 200), (910 * 140), ( 920 * 120) in a minimum of waste, ls002 empathy.
Finally, the effect of the field A1 is replaced by the following:
A0 (from growth ID) A1 (item number)
----------------------------- -
0 ls001- (920 * 120)
1 ls002- (220 * 320)
...
you have any good program or algorithm can learn to share what ^ _ ^
My solution:
-
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)
-
*/