----------------求一个复杂SQL-------------------

雄牛 2018-04-11 04:21:00
是这样的.有一下库存结算表,每天做一次结算,结算其实就是标识一个结算单号,记录每一种货品的库存数据(多次只记录一条货品),然后把昨天的库存数据存下来,算法在程序中已经完成.当前新生成的结算单,只会把这一天的变动算进来.但现在,有个变动需求是这样,就算这一天这个货品A没有出入库,也要把它昨天的库存数据复制一条下来插入数据,并指定新的报告单号...

我的SQL该怎么写呢?要在同一个表复制数据到新记录,并指定新的结算单号(此单号程序生成)

比如已有表生成机制是这样:

序号 结算单号 货品名称 期初库存 入库数 出库数 结余库存
----------------------------------------------------------------------------------------------------------
1 100011 A 0 200 100 100
2 100011 B 0 50 20 30
3 100012 A 100 0 10 90
4 100013 B 30 0 5 25


如果我要生成100012,或100013时,应该用什么方法生成以下的数据?(不用管期初,结余数据,这些数据是在程序算法中完成,现在就是要把不同的货品如果这一天没变动,也要把上一次的变动复制插入到新的结算单号中)

序号 结算单号 货品名称 期初库存 入库数 出库数 结余库存
----------------------------------------------------------------------------------------------------------
1 100011 A 0 200 100 100
2 100011 B 0 50 20 30
3 100012 A 100 0 10 90
4 100012 B 30 0 0 30
5 100013 B 30 0 5 25
6 100013 A 90 0 0 90
...全文
903 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
szlixiaolong 2018-04-18
  • 打赏
  • 举报
回复
学习这个复杂的SQL
道素 2018-04-16
  • 打赏
  • 举报
回复
仅供参考,你可以试试使用在你实际数据中,性能如何(有些其实可以不用这些写,比如如果你的货品名称有基础表,那么不需要用数据中去全部枚举出) 另外你这里没有时间戳,索引用单号来定位上一次

 select  i.结算单号,g.货品名称,isnull(d.期初库存,ld.结余库存) as 期初库存,isnull(d.入库数,0) as 入库数,ISNULL(d.出库数 ,0) as 出库数,isnull(d.结余库存,ld.结余库存) as 结余库存 
 from (select distinct 结算单号 from #inv ) as i
 inner join (select distinct 货品名称 from #inv ) as g on 1=1
 left join #inv as d on g.货品名称=d.货品名称 and i.结算单号=d.结算单号
 left join #inv as ld on g.货品名称=ld.货品名称 and i.结算单号=ld.结算单号+1
 order by i.结算单号,g.货品名称

+--------+------+------+-----+-----+------+
| 结算单号   | 货品名称 | 期初库存 | 入库数 | 出库数 | 结余库存 |
+--------+------+------+-----+-----+------+
| 100011 | A    | 0    | 200 | 100 | 100  |
| 100011 | B    | 0    | 50  | 20  | 30   |
| 100012 | A    | 100  | 0   | 10  | 90   |
| 100012 | B    | 30   | 0   | 0   | 30   |
| 100013 | A    | 90   | 0   | 0   | 90   |
| 100013 | B    | 30   | 0   | 5   | 25   |
+--------+------+------+-----+-----+------+
繁花尽流年 2018-04-12
  • 打赏
  • 举报
回复
select a.product_id from table a where a.bill_no='Axxxx1' not exists ( select 1 from table where bill_no='Axxxx2' and product_id=a.product_id ) 2000不支持except你用这个结构试试。组合主键最好用exists写不要用in
唐诗三百首 2018-04-12
  • 打赏
  • 举报
回复
SQL2000的写法如下,

-- 已有表生成机制是这样
create table #inv
(序号 int,结算单号 varchar(10),货品名称 varchar(10),期初库存 int,入库数 int,出库数 int,结余库存 int)

insert into #inv
 select 1,'100011','A',0,200,100,100 union all
 select 2,'100011','B',0,50,20,30 union all
 select 3,'100012','A',100,0,10,90 union all
 select 4,'100013','B',30,0,5,25


-- 补齐数据
insert into #inv(结算单号,货品名称,期初库存,入库数,出库数,结余库存)
select 结算单号=a.结算单号,
       货品名称=b.货品名称,
	   期初库存=isnull((select top 1 e.结余库存 
                       from #inv e 
			           where e.货品名称=b.货品名称
			           and e.结算单号<a.结算单号
			           order by e.结算单号 desc),0),
	   入库数=0,
	   出库数=0,
	   结余库存=isnull((select top 1 e.结余库存 
                       from #inv e 
			           where e.货品名称=b.货品名称
			           and e.结算单号<a.结算单号
			           order by e.结算单号 desc),0)
 from (select distinct 结算单号 from #inv) a
 cross join (select distinct 货品名称 from #inv) b
 left join #inv c on a.结算单号=c.结算单号
                     and b.货品名称=c.货品名称
 where c.结算单号 is null

select 序号=identity(int,1,1),结算单号,货品名称,期初库存,入库数,出库数,结余库存 
 into #inv2
 from #inv
 order by 结算单号,货品名称


-- 结果
select * from #inv2 order by 序号

/*
序号          结算单号       货品名称       期初库存        入库数         出库数         结余库存
----------- ---------- ---------- ----------- ----------- ----------- -----------
1           100011     A          0           200         100         100
2           100011     B          0           50          20          30
3           100012     A          100         0           10          90
4           100012     B          30          0           0           30
5           100013     A          90          0           0           90
6           100013     B          30          0           5           25

(6 row(s) affected)
*/
唐诗三百首 2018-04-12
  • 打赏
  • 举报
回复

-- 已有表生成机制是这样
create table #inv
(序号 int,结算单号 varchar(10),货品名称 varchar(10),期初库存 int,入库数 int,出库数 int,结余库存 int)

insert into #inv
 select 1,'100011','A',0,200,100,100 union all
 select 2,'100011','B',0,50,20,30 union all
 select 3,'100012','A',100,0,10,90 union all
 select 4,'100013','B',30,0,5,25


-- 补齐数据
update #inv set 序号=null

insert into #inv(结算单号,货品名称,期初库存,入库数,出库数,结余库存)
select 结算单号=a.结算单号,
       货品名称=b.货品名称,
	   期初库存=isnull(d.结余库存,0),
	   入库数=0,
	   出库数=0,
	   结余库存=isnull(d.结余库存,0)
 from (select distinct 结算单号 from #inv) a
 cross join (select distinct 货品名称 from #inv) b
 left join #inv c on a.结算单号=c.结算单号
                     and b.货品名称=c.货品名称
 outer apply(select top 1 e.结余库存 
              from #inv e 
			  where e.货品名称=b.货品名称
			  and e.结算单号<a.结算单号
			  order by e.结算单号 desc) d
 where c.结算单号 is null

update a
 set a.序号=b.rn
 from #inv a
 inner join (select rn=row_number() over(order by 结算单号,货品名称),
                    结算单号,
					货品名称
             from #inv) b on a.结算单号=b.结算单号 and a.货品名称=b.货品名称


-- 结果
select * from #inv order by 序号

/*
序号          结算单号       货品名称       期初库存        入库数         出库数         结余库存
----------- ---------- ---------- ----------- ----------- ----------- -----------
1           100011     A          0           200         100         100
2           100011     B          0           50          20          30
3           100012     A          100         0           10          90
4           100012     B          30          0           0           30
5           100013     A          90          0           0           90
6           100013     B          30          0           5           25

(6 row(s) affected)
*/
雄牛 2018-04-11
  • 打赏
  • 举报
回复
为什么我的SQL在SQL2000上无法执行出正确结果?

select ReportNO,ReportTime,LastReportNo,Client,PartName,Spec,Type,BeginBundle,InBundle,OutBundle,EndBundle,BeginQty,InQty,OutQty,EndQty,BeginCost,InCost,OutCost,EndCost 
from Checkclient 
where ID in(select max(b.ID) from Checkclient b where b.ReportNo<>'PR180411160310' group by b.Client,b.PartName,b.Spec)
and (Client+PartName+Spec) not in (Select Client+PartName+Spec from Checkclient where  ReportNo='PR180411160310' ) 
繁花尽流年 2018-04-11
  • 打赏
  • 举报
回复
引用 2 楼 cowbo 的回复:
[quote=引用 1 楼 zengertao 的回复:] 如果你新结算单已经能获取到发生变动的记录结果集,只需要用新单的【货品名称】和上一单的结果集【货品名称】EXCEPT下。 筛选出来【货品名称】的自然是当天没发生变动的,再把这批记录union all到新结算单里就好了。
程序的算法太长复杂,我只想在最后那段,用一个sql来插入数据,之前的机制是稳定的,改动挺不好整的. 比如,我现在要生成结算单的操作是 100012 可下面的SQL语句不行,有问题.


Insert into 结算表(结算单号       货品名称     期初库存     入库数           出库数      结余库存)
select 结算单号       货品名称     期初库存     入库数           出库数      结余库存
from 结算表 
where ID in(select max(b.ID) from 结算表b where b.结算单号 <>'100012' 
and b.ID not in (Select c.ID from 结算表c where c. 货品名称=b. 货品名称) 
group by  货品名称)

[/quote] 程序管原来运行也一样啊,只要你能拿到新结算单的结果集,最多当打个补丁加一段我上面逻辑的sql进去补没变动的货品库存就行了
雄牛 2018-04-11
  • 打赏
  • 举报
回复
引用 1 楼 zengertao 的回复:
如果你新结算单已经能获取到发生变动的记录结果集,只需要用新单的【货品名称】和上一单的结果集【货品名称】EXCEPT下。 筛选出来【货品名称】的自然是当天没发生变动的,再把这批记录union all到新结算单里就好了。
程序的算法太长复杂,我只想在最后那段,用一个sql来插入数据,之前的机制是稳定的,改动挺不好整的. 比如,我现在要生成结算单的操作是 100012 可下面的SQL语句不行,有问题.


Insert into 结算表(结算单号       货品名称     期初库存     入库数           出库数      结余库存)
select 结算单号       货品名称     期初库存     入库数           出库数      结余库存
from 结算表 
where ID in(select max(b.ID) from 结算表b where b.结算单号 <>'100012' 
and b.ID not in (Select c.ID from 结算表c where c. 货品名称=b. 货品名称) 
group by  货品名称)

繁花尽流年 2018-04-11
  • 打赏
  • 举报
回复
如果你新结算单已经能获取到发生变动的记录结果集,只需要用新单的【货品名称】和上一单的结果集【货品名称】EXCEPT下。 筛选出来【货品名称】的自然是当天没发生变动的,再把这批记录union all到新结算单里就好了。

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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