在论坛中出现的比较难的sql问题:30(row_number函数 物料组合问题)

本文介绍了一种在MS-SQL环境下实现的物料匹配算法,该算法通过对比表A的需求规格与表B的库存规格,找出浪费最小的物料进行替换。具体实现包括创建表结构、插入测试数据及编写SQL查询过程。

 

在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。

所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。


MS-SQL 根据实际所需规格table去比对另一个库存table取浪费最少的数据

 

http://bbs.youkuaiyun.com/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)
*/

 

转载于:https://www.cnblogs.com/momogua/p/8304474.html

CREATE OR REPLACE TYPE TYPE_MTRL_ROW AS OBJECT(pageNumber NUMBER, fenlei VARCHAR2(1024), bianma VARCHAR2(128), banben VARCHAR2(32), mingcheng VARCHAR2(128), guige VARCHAR2(4000), pinpai VARCHAR2(4000), caizhi VARCHAR2(512), zhuangtai CHAR(9), danwei VARCHAR2(1024), chuangjianshijian DATE, chuangjianren VARCHAR2(64), wlyxj VARCHAR2(1024)); CREATE OR REPLACE TYPE TYPE_MTRL_TABLE AS TABLE OF TYPE_MTRL_ROW; CREATE OR REPLACE FUNCTION PLM1."RUNA_SEL_MTRL"( P_BIANMA IN VARCHAR2, --编码 P_MINGCHENG IN VARCHAR2, --名称 P_GUIGE IN VARCHAR2, --规格 P_WLYXJ IN VARCHAR2, --物料优先级 P_startIndex IN INTEGER, --分页起始行 P_endIndex IN INTEGER --分页截止行 ) RETURN TYPE_MTRL_TABLE AS TEMP_ROW TYPE_MTRL_ROW; -- 定义单行 TEMP_TABLE TYPE_MTRL_TABLE; -- 定义返回结果,并初始化 v_sql VARCHAR2(2000); -- 定义单行 v_result VARCHAR2(2000); BEGIN v_sql := 'select * from (select row_number() over(order by chuangjianshijian desc) pageNumber, fenlei, bianma, banben, mingcheng, guige, guige as pinpai, caizhi, zhuangtai, danwei, chuangjianshijian, chuangjianren, wlyxj from "wuliao" where 1 = 1'; IF P_BIANMA IS NOT NULL THEN v_sql := v_sql || ' and bianma LIKE ''%' || P_BIANMA || '%'''; END IF; IF P_MINGCHENG IS NOT NULL THEN v_sql := v_sql || ' and mingcheng LIKE ''%' || P_MINGCHENG || '%'''; END IF; IF P_WLYXJ IS NOT NULL THEN v_sql := v_sql || ' and wlyxj LIKE ''%' || P_WLYXJ || '%'''; END IF; IF P_GUIGE IS NOT NULL THEN FOR i IN 1..LENGTH(P_GUIGE) + 1 LOOP v_result := REGEXP_SUBSTR(P_GUIGE, '[^ ]+', 1, i); EXIT WHEN v_result IS NULL; v_sql := v_sql || ' and guige LIKE ''%' || v_result || '%'''; END LOOP; END IF; v_sql := v_sql || ') aa where pageNumber between ' || P_startIndex || ' + 1 and ' || P_endIndex; EXECUTE IMMEDIATE v_sql BULK COLLECT INTO TEMP_TABLE; RETURN TEMP_TABLE; END; 上述数据库函数执行时,提示异常“ORA-00932: 数据类型不一致: 应为 -, 但却获得 -”,请分析错误原因
最新发布
07-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值