使用SQL查询分析实现类收发存的报表,原始需求在 另外一篇文章 的第四部分。下图是实现需求。

一、准备

删除临时表


[buy]判断是否存在临时表,存在则删除[/buy] if OBJECT_ID('tempdb..#inv') is not null
drop table #inv
if OBJECT_ID('tempdb..#t_mto') is not null
drop table #t_MTO
if OBJECT_ID('tempdb..#t_mtoentry') is not null
drop table #t_MTOEntry

判断是否存在需调整记录

[buy]判断采购申请单上是否存在需要调整的记录,存在则继续。

需要满足条件是:

1.采购申请单上存在MTO计划模式的物料,计划跟踪号不为999999;

2.库存中有可调整的物料。

那么库存中哪些是可以调整的物料呢?还得满足以下条件:

2.1批号为999999;

2.2计划跟踪号为空或者999999;

3.3无浮动计量单位的,基本库存数量要大于0,有浮动计量单位的,辅助数量和基本数量的库存均需大于0;

[/buy]

declare @finterid int = 1059
if exists (select f1 from (
select case when (ti.FSecUnitID = 0 and t2.FQty > 0) OR (ti.FSecUnitID > 0 and t2.FQty > 0 and t2.FSecQty > 0 ) then 1 else 0 end as "F1"
from PORequestEntry t1
left join ICInventory t2 on t1.FItemID = t2.FItemID
left join t_ICItem ti on t1.FItemID = ti.FItemID
where t1.FInterID = @finterid
and t1.FPlanMode = '14035'
and t1.FMTONo <> '999999'
and t2.FBatchNo = '999999'
and t2.FMTONo in ('','999999')
) as t where f1 = 1
)

二、开始

begin

寻找内码

查询mto调整单的内码

	declare @maxNum int
select @maxNum = FMaxNum from ICMaxNum where FTableName = 't_MTOChange'
set @maxNum = @maxNum + 1
update ICMaxNum set FMaxNum = @maxNum

构建表结构

将采购申请、存货表、需计算的字段进行联结,并构成临时表#inv

	select
t3.FBillNo,
t1.FEntryID,
t1.FDetailID,
t1.FItemID,
t1.FMTONo as "t1FMTONo",
ti.FSecUnitID,
t1.FQty as "t1FQty",
t1.FCommitQty,
t1.FUnitID,
tm.FCoefficient,
t1.FAuxCommitQty,
t1.FAuxQty,
t1.FSecQty as "t1FSecQty",
t1.FSecCommitQty,
t1.FOrderQty,
t1.FMRPClosed,
t1.FPlanMode,
t1.FEntrySelfP0139, --辅助数量(计算)
t1.FEntrySelfP0140, --关联数量
t1.FEntrySelfP0141, --关联标志
t2.FStockID,
t2.FStockPlaceID,
t2.FKFPeriod,
t2.FKFDate,
t2.FQty as "t2FQty",
t2.FSecQty as "t2FSecQty",
case when t2.FSecQty > 0 then t2.FQty / t2.FSecQty else 0 end as "FSecCoefficient",
t2.FBatchNo,
t2.FMTONo as "t2FMTONo",
CAST(null as int) as "FMTOInterID",
CAST(null as decimal(28,10)) as "FChaQty",
cast(null as decimal(28,10)) as "FMTOChange",
cast(null as decimal(28,10)) as "FSumMTOChange",
CAST(null as decimal(28,10)) as "FBegQty",
CAST(null as decimal(28,10)) as "FEndQty", cast(null as decimal(28,10)) as "FSecChaQty",
cast(null as decimal(28,10)) as "FSecMTOChange",
cast(null as decimal(28,10)) as "FSecSumMTOChange",
CAST(null as decimal(28,10)) as "FSecBegQty",
CAST(null as decimal(28,10)) as "FSecEndQty", DENSE_RANK() OVER (ORDER BY t1.FItemID) AS RANK1,
ROW_NUMBER() over (PARTITION by t1.FDetailID order By t1.FEntryID,t2.FMTONo,t2.FQty desc) RANK2 into #inv
from PORequestEntry t1
left join ICInventory t2 on t1.FItemID = t2.FItemID
left join t_ICItem ti on t1.FItemID = ti.FItemID
left join t_MeasureUnit tm on t1.FUnitID = tm.FMeasureUnitID
left join PORequest t3 on t1.FInterID =t3.FInterID
where t1.FInterID = @finterid
and t1.FPlanMode = '14035'
and t1.FMTONo <> '999999'
and t2.FBatchNo = '999999'
and t2.FMTONo in ('','999999')
and t2.FQty > 0
and ((ti.FSecUnitID = 0 and t2.FQty > 0) OR (ti.FSecUnitID > 0 and t2.FQty > 0 and t2.FSecQty > 0 ))

更新

更新#inv表的MTO调整单内码

	update #inv set FMtoInterID = @maxNum

构建临时表

用来存放mto调整单的表头数据

	create table #t_MTO(
FID int,
FClassTypeID int,
FTranType int,
FBillNo nvarchar(255),
FDate datetime,
FNote nvarchar(255),
FBillerID int,
FCheckDate datetime,
FEmpID int,
FCheckerID int,
FDeptID int,
FStatus smallint,
FUpStockWhenSave bit,
FPrintCount int,
FSourceBillNo nvarchar(50),
FSourceTranType int
)

用来存放mto调整单的表体数据

	create table #t_MTOEntry(
FID int,
FIndex int,
FItemID int,
FAuxPropID int,
FBatchNo varchar(255),
FStockID int,
FSPID int,
FBaseQty decimal(23,10),
FSecUnitID int,
FUnitID int,
FQty decimal(23,10),
FSecCoefficient decimal(23,10),
FSecQty decimal(23,10),
FChangeQty_Base decimal(23,10),
FChangeQty decimal(23,10),
FChangeSecQty decimal(23,10),
FKFDate datetime,
FKFPeriod int,
FPeriodDate datetime,
FFromMTONo nvarchar(50),
FToMTONo nvarchar(50),
FChangeBaseQty decimal(23,10),
FSelectedProcID int,
FEntrySupply int,
FStockTypeID int,
FMrpNo nvarchar(50)
)

三、计算

	declare @R1 int = 1
declare @maxR int = (select MAX(RANK1) from #inv)
while @R1 <= @maxR begin
if OBJECT_ID('tempdb..#inv2') is not null
drop table #inv2
select *,DENSE_RANK() OVER (ORDER BY FDetailID) AS RANK3 into #inv2 from #inv where RANK1 = @R1 declare @FSecUnitID int = (select top(1) FSecUnitID from #inv2 where RANK1 = @R1) if @FSecUnitID = 0 begin --没有辅助单位的
declare @R2 int = 1
declare @maxR2 int = (select MAX(RANK2) from #inv2 where RANK3 = 1)
declare @FChaQty decimal(28,10) = (select t1FQty from #inv2 where RANK2 = 1 and RANK3 = 1)
while @R2 <= @maxR2 begin
set @FChaQty = @FChaQty - (select t2FQty from #inv2 where RANK2 = @R2 and RANK3 = 1)
update #inv2 set FChaQty = @FChaQty where RANK2 = @R2 and RANK3 = 1
if @FChaQty > 0 update #inv2 set FMTOChange = t2FQty where RANK2 = @R2 and RANK3 = 1
if @FChaQty <=0 update #inv2 set FMTOChange = t2FQty + FChaQty where RANK2 = @R2 and RANK3 = 1
update #inv2 set FSumMTOChange = (select SUM(FMTOChange) from #inv2 where RANK3 = 1 and FMTOChange > 0) where RANK3 = 1
update #inv2 set FMRPClosed = case when (FSumMTOChange - t1FQty >= 0 ) then 1 else 0 end where RANK3 = 1
update #inv2 set FEndQty = t2FQty - FMTOChange where RANK3 = 1 and FMTOChange > 0
update #inv2 set FEndQty = t2FQty where RANK3 = 1 and FMTOChange <= 0
set @R2 = @R2 +1
end declare @R3 int = 1
declare @maxR3 int = (select MAX(RANK3) from #inv2)
while @R3 <= @maxR3 begin declare @i int = 1
declare @maxI int = (select MAX(rank2) from #inv2 where RANK3 = @R3)
while @i <= @maxI begin
update #inv2 set FBegQty = t2FQty where RANK2 = @i and RANK3 = 1
update #inv2 set FBegQty = (select FEndQty from #inv2 where RANK2 = @i and RANK3 = @R3 and FEndQty >0) where RANK2 = @i and RANK3 = @R3+1
set @i = @i + 1
end declare @R31 int = 2
while @R31 <= @maxR3 begin declare @j int = (select min(RANK2) from #inv2 where FBegQty >0 and RANK3 = @R31)
declare @maxJ int = (select max(RANK2) from #inv2 where FBegQty >0 and RANK3 = @R31)
declare @FChaQty2 decimal(28,10)= (select t1FQty from #inv2 where RANK2 = 1 and RANK3 = @R31)
while @j <= @maxJ begin
set @FChaQty2 = @FChaQty2 - (select FBegQty from #inv2 where RANK2 = @j and RANK3 = @R31)
update #inv2 set FChaQty = @FChaQty2 where RANK2 = @j and RANK3 = @R31
if @FChaQty2 > 0 update #inv2 set FMTOChange = FBegQty where RANK2 = @j and RANK3 = @R31
if @FChaQty2 <=0 update #inv2 set FMTOChange = FBegQty + FChaQty where RANK2 = @j and RANK3 = @R31
update #inv2 set FSumMTOChange = (select SUM(FMTOChange) from #inv2 where RANK3 = @R31 and FMTOChange >0) where RANK3 = @R31
update #inv2 set FMRPClosed = case when (FSumMTOChange - t1FQty >= 0 ) then 1 else 0 end where RANK3 = @R31
update #inv2 set FEndQty = FBegQty - FMTOChange where RANK3 = @R31 and FMTOChange > 0
update #inv2 set FEndQty = FBegQty where RANK3 = @R31 and FMTOChange <= 0
set @j = @j+1
end
set @R31 = @R31 +1
end
set @R3 = @R3 + 1
end
end if @FSecUnitID >0 begin --有辅助单位的
declare @R2s int = 1
declare @maxR2s int = (select MAX(RANK2) from #inv2 where RANK3 = 1)
declare @FSecChaQty decimal(28,10) = (select FEntrySelfP0139 from #inv2 where RANK2 = 1 and RANK3 = 1)
while @R2s <= @maxR2s begin
set @FSecChaQty = @FSecChaQty - (select t2FSecQty from #inv2 where RANK2 = @R2s and RANK3 = 1)
update #inv2 set FSecChaQty = @FSecChaQty where RANK2 = @R2s and RANK3 = 1
if @FSecChaQty > 0 update #inv2 set FSecMTOChange = t2FSecQty where RANK2 = @R2s and RANK3 = 1
if @FSecChaQty <=0 update #inv2 set FSecMTOChange = t2FSecQty + FSecChaQty where RANK2 = @R2s and RANK3 = 1
update #inv2 set FSecSumMTOChange = (select SUM(FSecMTOChange) from #inv2 where RANK3 = 1 and FSecMTOChange > 0) where RANK3 = 1
update #inv2 set FMRPClosed = case when (FSecSumMTOChange - FEntrySelfP0139 >= 0 ) then 1 else 0 end where RANK3 = 1
update #inv2 set FSecEndQty = t2FSecQty - FSecMTOChange where RANK3 = 1 and FSecMTOChange > 0
update #inv2 set FSecEndQty = t2FSecQty where RANK3 = 1 and FSecMTOChange <= 0 update #inv2 set FMTOChange = FSecMTOChange * FSecCoefficient where RANK2 = @R2s and RANK3 = 1
update #inv2 set FSumMTOChange = (select SUM(FMTOChange) from #inv2 where RANK3 = 1 and FMTOChange > 0) where RANK3 = 1
update #inv2 set FEndQty = t2FQty - FMTOChange where RANK3 = 1 and FMTOChange > 0
update #inv2 set FEndQty = t2FQty where RANK3 = 1 and FMTOChange <= 0
set @R2s = @R2s +1
end declare @R3s int = 1
declare @maxR3s int = (select MAX(RANK3) from #inv2)
while @R3s <= @maxR3s begin declare @is int = 1
declare @maxIs int = (select MAX(rank2) from #inv2 where RANK3 = @R3s)
while @is <= @maxIs begin
update #inv2 set FSecBegQty = t2FSecQty where RANK2 = @is and RANK3 = 1
update #inv2 set FSecBegQty = (select FSecEndQty from #inv2 where RANK2 = @is and RANK3 = @R3s and FSecEndQty >0) where RANK2 = @is and RANK3 = @R3s+1 update #inv2 set FBegQty = t2FQty where RANK2 = @is and RANK3 = 1
update #inv2 set FBegQty = (select FEndQty from #inv2 where RANK2 = @is and RANK3 = @R3s and FEndQty >0) where RANK2 = @is and RANK3 = @R3s+1
set @is = @is + 1
end declare @R31s int = 2
while @R31s <= @maxR3s begin declare @js int = (select min(RANK2) from #inv2 where FSecBegQty >0 and RANK3 = @R31s)
declare @maxJs int = (select max(RANK2) from #inv2 where FSecBegQty >0 and RANK3 = @R31s)
declare @FSecChaQty2 decimal(28,10)= (select FEntrySelfP0139 from #inv2 where RANK2 = 1 and RANK3 = @R31s)
while @js <= @maxJs begin
set @FSecChaQty2 = @FSecChaQty2 - (select FSecBegQty from #inv2 where RANK2 = @js and RANK3 = @R31s)
update #inv2 set FSecChaQty = @FSecChaQty2 where RANK2 = @js and RANK3 = @R31s
if @FSecChaQty2 > 0 update #inv2 set FSecMTOChange = FSecBegQty where RANK2 = @js and RANK3 = @R31s
if @FSecChaQty2 <=0 update #inv2 set FSecMTOChange = FSecBegQty + FSecChaQty where RANK2 = @js and RANK3 = @R31s
update #inv2 set FSecSumMTOChange = (select SUM(FSecMTOChange) from #inv2 where RANK3 = @R31s and FSecMTOChange >0) where RANK3 = @R31s
update #inv2 set FMRPClosed = case when (FSecSumMTOChange - FEntrySelfP0139 >= 0 ) then 1 else 0 end where RANK3 = @R31s
update #inv2 set FSecEndQty = FSecBegQty - FSecMTOChange where RANK3 = @R31s and FSecMTOChange > 0
update #inv2 set FSecEndQty = FSecBegQty where RANK3 = @R31s and FSecMTOChange <= 0 update #inv2 set FMTOChange = FSecMTOChange * FSecCoefficient where RANK2 = @js and RANK3 = @R31s
update #inv2 set FSumMTOChange = (select SUM(FMTOChange) from #inv2 where RANK3 = @R31s and FMTOChange > 0 ) where RANK3 = @R31s
update #inv2 set FEndQty = FBegQty - FMTOChange where RANK3 = @R31s and FMTOChange > 0
update #inv2 set FEndQty = FBegQty where RANK3 = @R31s and FMTOChange <= 0
set @js = @js+1
end
set @R31s = @R31s +1
end
set @R3s = @R3s + 1
end
end select * from #inv2

四、结束

反写采购申请明细表

		update te set
te.FMRPClosed = ti.FMRPClosed,
te.FCommitQty = ti.FSumMTOChange,
te.FAuxCommitQty = ti.FSumMTOChange / ti.FCoefficient,
te.FSecCommitQty = case when ti.FSecSumMTOChange IS null then 0 else ti.FSecSumMTOChange end,
te.FOrderQty = ti.FSumMTOChange,
te.FEntrySelfP0140 = case when ti.FSecUnitID = 0 then ti.FSumMTOChange else ti.FSecSumMTOChange end,
te.FEntrySelfP0141 = 1
from PORequestEntry te,#inv2 ti where te.FDetailID = ti.FDetailID

插入MTO单据体临时表

		insert into #t_MTOEntry
select
FMTOInterID,
'' as "FIndex",
FItemID,
'0' as "FAuxPropID",
FBatchNo,
FStockID,
FStockPlaceID,
FBegQty,
null as "FSecUnitID",
FUnitID,
FBegQty / FCoefficient as "FQty",
FSecCoefficient,
case when FSecBegQty is null then 0 else FSecBegQty end as "FSecQty",
'0' as FChangeQty_Base,
FMTOChange / FCoefficient as "FChangeQty",
case when FSecMTOChange is null then 0 else FSecMTOChange end as "FChangeSecQty",
case when (FKFDate = '') then null else FKFDate end AS "FKFDate",
FKFPeriod,
case when (FKFDate = '') then null else FKFDate + FKFPeriod end AS "FPeriodDate",
t2FMTONo,
t1FMTONo,
FMTOChange,
'',
'',
'',
''
from #inv2 where FMTOChange > 0
set @R1 = @R1+1
end

插入MTO单据头临时表

	insert into #t_MTO
select
FMTOInterID,
1107011,
1107011,
'MTOAUTO'+LTRIM(str(FMTOInterID)),
CONVERT(varchar(10),getdate(),23)+' 00:00:00.000',
'',
16394,
GETDATE(),
2649,
16394,
277,
1,
0,
0,
FBillNo,
70
from #inv2

插入数据表

	insert into t_MTOChange select * from #t_MTO
insert into t_MTOChangeEntry select * from #t_MTOEntry

插入审批流

	Insert Into ICClassCheckRecords1107011(FPage,FBillID,FBillEntryID,FBillNo, FBillEntryIndex,FCheckLevel,FCheckLevelTo,FMode,FCheckMan, FCheckIdea,FCheckDate,FDescriptions)
Values (1,@maxnum,0,'MTOAUTO'+ltrim(str(@maxnum)),0,-99,-1,0,16394,'',GetDate(),'审核')
Insert Into ICClassCheckRecords1107011(FPage,FBillID,FBillEntryID,FBillNo, FBillEntryIndex,FCheckLevel,FCheckLevelTo,FMode,FCheckMan, FCheckIdea,FCheckDate,FDescriptions)
Values (1,@maxnum,0,'MTOAUTO'+ltrim(str(@maxnum)),0,-1,1,0,16394,'',GetDate(),'审核')

校对即时库存

	EXEC CheckInventory

更新采购申请单单据头MTO内码

	update PORequest set FChildren = FChildren + 1,FHeadSelfP0134 = @maxNum where FInterID = @finterid

结束

end

用SQL查询分析实现类似金蝶K3的收发存明细表的更多相关文章

  1. Red Gate系列之七 SQL Search 1.1.6.1 Edition SQL查询分析工具使用教程

    原文:Red Gate系列之七 SQL Search 1.1.6.1 Edition SQL查询分析工具使用教程 Red Gate系列之七 SQL Search 1.1.6.1 Edition SQL ...

  2. SQL查询性能分析

    http://blog.csdn.net/dba_huangzj/article/details/8300784 SQL查询性能的好坏直接影响到整个数据库的价值,对此,必须郑重对待. SQL Serv ...

  3. [转]一个用户SQL慢查询分析,原因及优化

    来源:http://blog.rds.aliyun.com/2014/05/23/%E4%B8%80%E4%B8%AA%E7%94%A8%E6%88%B7sql%E6%85%A2%E6%9F%A5%E ...

  4. MyBatis原理分析之四:一次SQL查询的源码分析

    上回我们讲到Mybatis加载相关的配置文件进行初始化,这回我们讲一下一次SQL查询怎么进行的. 准备工作 Mybatis完成一次SQL查询需要使用的代码如下: ) { ); ) { throw ne ...

  5. SQL查询性能分析之(not in)、(and not)、()、(!=)性能比较

    SQL查询性能分析之(not in).(and not).().(!=)性能比较 SQL Server Bruce 3年前 (2013-01-08) 3284浏览 0评论 <:article c ...

  6. sql查询未走索引问题分析之查询数据量过大

    前因: 客户咨询,有一个业务sql(代表经常被执行且重要),全表扫描在系统占用资源很高(通过ash报告查询得到信息) 思路: 1.找到sql_text,sql_id 2.查看执行计划 3.查询sql涉 ...

  7. MySQL与OLAP:分析型SQL查询最佳实践探索

    搞点多维分析,糙快猛的解决方式就是使用ROLAP(关系型OLAP)了.数据经维度建模后存储在MySQL,ROLAP引擎(比方开源的Mondrian)负责将OLAP请求转化为SQL语句提交给数据库.OL ...

  8. sql优化 慢查询分析

    查询速度慢的原因很多,常见如下几种 SQL慢查询分析 转自:https://www.cnblogs.com/firstdream/p/5899383.html 1.没有索引或者没有用到索引(这是查询慢 ...

  9. SQL查询速度慢的原因分析和解决方案

    SQL查询速度慢的原因分析和解决方案 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建 ...

随机推荐

  1. C# 添加、修改、删除PPT中的超链接

    本文介绍通过C# 编程如何在PPT幻灯片中添加超链接的方法,添加链接时,可给文本或者图片添加超链接,链接对象可指向网页地址.邮件地址.指定幻灯片等,此外,也可以参考文中编辑.删除幻灯片中已有超链接的方 ...

  2. Python IDE ——Anaconda+PyCharm的安装与配置

    一 前言 最近莫名其妙地想学习一下Python,想着利用业余时间学习一下机器学习(或许仅仅是脑子一热吧).借着研究生期间对于PyCharm安装的印象,在自己的电脑上重新又安装了一遍.利用周末的一点时间 ...

  3. [React]Hook初探

    Hook是什么 Hook是React从16.8开始支持的特性,使用Hook可以在不使用class时使用state Hook支持在不需要修改组件状态的情况下复用逻辑状态,从而解决使用render pro ...

  4. 一文读懂什么是CA证书

    Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable ...

  5. Java序列化机制剖析

    本文转载自longdick的博文<Java序列化算法透析>,原文地址:http://longdick.iteye.com Java序列化算法透析 Serialization(序列化)是一种 ...

  6. CodeForces - 817B(分类讨论 + 排列组合)

    题目链接 思路如下 这一题是:最菜的队伍只有三个人组成,我们只需对排序后的数组的 前三个元素进行分类讨论即可: a[3] != a[2] && a[3] != ar[1] a[3] = ...

  7. 并发——抽象队列同步器AQS的实现原理

    一.前言   这段时间在研究Java并发相关的内容,一段时间下来算是小有收获了.ReentrantLock是Java并发中的重要部分,所以也是我的首要研究对象,在学习它的过程中,我发现它是基于抽象队列 ...

  8. Scheme语言实例入门--怎样写一个“新型冠状病毒感染风险检测程序”

    小学生都能用的编程语言 2020的春季中小学受疫情影响,一直还没有开学,孩子宅在家说想做一个学校要求的研究项目,我就说你做一个怎么样通过编程来学习数学的小项目吧,用最简单的计算机语言来解决小学数学问题 ...

  9. 痞子衡嵌入式:走进二维码(QR Code)的世界(1)- 引言

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是走进二维码(QR Code)的世界专题的引言. 如今二维码可以说是深入走进大家的生活了,推送名片.扫码支付都离不开它,大家几乎每天都会和 ...

  10. 如何用VmwareWorkstation安装Centos系统

    教你如何安装虚拟机系统 首先你得有虚拟化软件,常用的VmwareWorkstation一般能满足日常需求. 下载地址,请自行搜索. 第一步,新建虚拟机 选择安装系统源 这里有三个选项. 1.第一个是使 ...