xys_777请进

dongdongxiao 2010-06-07 11:58:12
xys_777 的解释很详细,谢谢!



if object_id('tb_a') is not null drop table tb_a
go
create table tb_a
( owner char(2) null,
skuid varchar(10) null,
lot varchar(50) null,
quality varchar(2) null,
vol decimal(18,2) null,
vol_exchange decimal(18,2) null,
mysort int
)
if object_id('tb_b') is not null drop table tb_b
go
create table tb_b
( owner char(2) null,
skuid varchar(10) null,
lot varchar(50) null,
quality varchar(2) null,
vol decimal(18,2) null,
vol_exchange decimal(18,2) null,
mysort int
)
set nocount on
INSERT INTO tb_a(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '78 ', '1000164481 ', '071203 ', '0 ',80.00,70.00,1)
INSERT INTO tb_a(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '78 ', '1000164481 ', '071202 ', '0 ',60.00,0.00,2)
INSERT INTO tb_a(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '78 ', '1000164481 ', '081203 ', '0 ',30.00,30.00,3)
INSERT INTO tb_a(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '78 ', '1000164481 ', '081202 ', '0 ',20.00,20.00,4)
INSERT INTO tb_a(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '78 ', '1000164481 ', '081201 ', '0 ',10.00,10.00,5)

INSERT INTO tb_b(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '01 ', '1000164479 ', '091201 ', '0 ',18.00,6.00,6)
INSERT INTO tb_b(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '04 ', '1000164481 ', '091201 ', '0 ',20.00,0.00,5)
INSERT INTO tb_b(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '03 ', '1000164479 ', '091201 ', '0 ',26.00,26.00,4)
INSERT INTO tb_b(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '02 ', '1000164479 ', '091201 ', '0 ',28.00,28.00,3)
INSERT INTO tb_b(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '08 ', '1000164481 ', '091201 ', '0 ',60.00,0.00,2)
INSERT INTO tb_b(owner,skuid,lot,quality,vol,vol_exchange,mysort)
VALUES ( '06 ', '1000164481 ', '091201 ', '0 ',80.00,70.00,1)
set nocount off
GO


--这段我简单看了一下阿,因为我也写过,只是写法不同,但是思路完全相同。但是很难理解

select * from
(
select a.owner as owner_a,b.owner as owner_b,b.skuid,b.lot as in_lot,a.lot as out_lot,
case when a.v2<=b.V2 then --当前B提供总数多与A的需要数量时
case when a.v2-b.V1<=a.vol_exchange -- B的剩余 <= 当前A的需要 显示B可提供的值,否则显示A的数量
then a.v2-b.V1 else a.vol_exchange end
else b.V2 - a.v1 --当前B可提供的和不能满足A的数量时,显示可以提供的数量
end as vol_exchange,
a.mysort asort,b.mysort bsort
from
(select top 100 percent * ,
isnull((select sum(vol_exchange) from tb_a where mysort<A.mysort and vol_exchange>0),0) as V1, --求出当前行之前所有需要分配的数量总合
isnull((select sum(vol_exchange) from tb_a where mysort<=A.mysort and vol_exchange>0),0) as V2 --求出到当前行所有需要分配的数量总合
from tb_a A
where vol_exchange>0
order by mysort) as A,
(select top 100 percent owner,skuid,lot,quality,vol,vol_exchange as vol_exchange,mysort ,
isnull((select sum(vol_exchange) from tb_b where mysort<B.mysort and vol_exchange>0),0) as V1,--求出当前行之前所有可以分配的数量总合
isnull((select sum(vol_exchange) from tb_b where mysort<=B.mysort and vol_exchange>0),0) as V2 --求出到当前行所有可以分配的数量总合
from tb_b B
where vol_exchange>0
order by mysort) as B

--这两个条件和在一起就是,当前A的所有vol_exchange的和要小于等于当前B提供的vol_exchange的和,但一定要大于等于B当前行之前所有vol_exchange的和

where a.V2>=b.V1 --这里就是当前需要分配总数 要大于等于 可提供的数数量(并且是不包含当前那个tb_b的可提供的数量(在第二个条件上判断包括当前B的和),刚好分配到B的最后一个或是倒数第二个合适的数据)
and a.V1<=b.V2 --这里判断B是否可以为A提供数据进行分配,V1是A可以分配的那行前所有 vol_exchange的和。也就是当前提供一定要满足为A当前行之前所有行的和,才能为当前A提供数据,当然这里有等号,包含了一些重复数据(即可以提供的数据是0的数据,这个是在最外层的select里除去)
/*
执行:

A=70
70 >= 0 and 0<= 70 (总需求 70 ,之前需求 0 ,符合但提供数据值为 70 );;2: 70>=70 and 0<=98;3: 70>=98 and 0<=124
A=30
100>=0 and 70<=70 (总需求 100 ,之前需求 70 ,符合但提供数据值为 0 ); 100>=70 and 70<=98 (总需求 100 ,之前需求 70 ,符合提供数据值为 28 );100>=98 and 70<=124 100>=124 and 70<=98
A=20
120>=0 and 124<=70 ...120>=98 and 100<=124 (总需求 100 ,之前需求 70 ,符合提供数据值为 20 );
......
*/
) X
where vol_exchange>0
order by asort,bsort

/*
owner_a owner_b skuid in_lot out_lot vol_exchange asort bsort
------- ------- ---------- -------------------------------------------------- -------------------------------------------------- ---------------------------------------- ----------- -----------
78 06 1000164481 091201 071203 70.00 1 1
78 02 1000164479 091201 081203 28.00 3 3
78 03 1000164479 091201 081203 2.00 3 4
78 03 1000164479 091201 081202 20.00 4 4
78 03 1000164479 091201 081201 4.00 5 4
78 01 1000164479 091201 081201 6.00 5 6

(所影响的行数为 6 行)

*/
...全文
114 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
playwarcraft 2010-06-07
  • 打赏
  • 举报
回复
LZ分多~~~求包养~~~
永生天地 2010-06-07
  • 打赏
  • 举报
回复
lz需要在脑海里设置去运行那段代码

或者拿出纸和笔,按照select的每一次循环,分别去赋值执行
dongdongxiao 2010-06-07
  • 打赏
  • 举报
回复
级别低,水平低,但可用分多(注册早,还有4K多分,呵呵)

还是要感谢各位。呵呵!
-狙击手- 2010-06-07
  • 打赏
  • 举报
回复
学习。。。
htl258_Tony 2010-06-07
  • 打赏
  • 举报
回复
楼主厚道
dongdongxiao 2010-06-07
  • 打赏
  • 举报
回复
问题如下:

简单看来,可以把A表看成是需求表
B表看成是供应表。
skuid 看成是某种类型,只有同类型的才可供应。
SQL code

owner skuid lot quality vol_exchange mysort
78 A 071203 0 70.00 1

78 B 081203 0 30.00 3
78 B 081202 0 20.00 4
78 B 081201 0 10.00 5

owner skuid lot quality vol_exchange mysort
06 A 091201 0 70.00 1

02 B 091201 0 28.00 3 --需求30,缺2,只能下笔补上
03 B 091201 0 26.00 4 -- (只剩24,因为2被上面那笔吃掉了),够第三笔需求20的,还剩下4,可供给第四笔需求

01 B 091201 0 6.00 6



所以,第一笔需要A 70, 正好 供应 A 70
第二笔需要B 30,供应的话,第二笔只有B 28 , 缺2
所以会将第三笔供应拆成 26 = 2+24
第三笔需求20,第三笔供应还有24,够的。
第四笔需求10,第三笔供应还多4,给它。加上第四笔供应6.

SQL code

所以,最后结果
需求 供应
A 70 A 70
B 30 B 28
B 30 B 2 -- 26那借来的
B 20 B 20 --还多4呢
B 10 B 4 --多的4给这了
B 10 B 6

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧