22,302
社区成员




use Tempdb
go
--> --> 中国风(Roy)生成測試數據
if not object_id(N'Tempdb..#1') is null
drop table #1
Go
Create table #1([单据编号] nvarchar(31),[物料编号] nvarchar(38),[批号] nvarchar(31),[数量] int)
Insert #1
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160218-06',67 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160394-06',56 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160407-05',34 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160416-07',48 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160218-07',23 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160394-07',56 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160407-06',34 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160410-01',5 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160416-08',48 union all
select N'KMR16004681',N'CTN2007131A-/2',N'SC160218-11',225 union all
select N'KMR16004681',N'CTN2007131A-/2',N'SC160394-10',100 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'SC160416-12',720 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'SC160548-05',480 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'SC160416-12',180 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'SC160548-05',120
Go
--> --> 中国风(Roy)生成測試數據
if not object_id(N'Tempdb..#2') is null
drop table #2
Go
Create table #2([单据编号] nvarchar(31),[物料编号] nvarchar(38),[拆分后单据编号] nvarchar(33),[数量] int)
Insert #2
select N'KMR16004350',N'CTN2006164D-/36R1',N'KMR16004350',67 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'KMR16004350-1',138 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'KMR16004350',166 union all
select N'KMR16004681',N'CTN2007131A-/2',N'KMR16004681-1',225 union all
select N'KMR16004681',N'CTN2007131A-/2',N'KMR16004681-2',100 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465',228 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465-1',272 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465-2',220 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465-3',480 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465',57 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465-1',68 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465-2',55 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465-3',120
GO
;WITH a
AS
(SELECT *,(SELECT SUM([数量]) FROM #1 WHERE [物料编号]=a.[物料编号] AND ([单据编号]<a.[单据编号] OR [单据编号]=a.[单据编号] AND [批号]<=a.[批号])) AS SumQty1 FROM #1 AS a)
,b AS
(SELECT *,(SELECT SUM([数量]) FROM #2 WHERE [物料编号]=a.[物料编号] AND ([单据编号]<a.[单据编号] OR [单据编号]=a.[单据编号] AND [拆分后单据编号]<=a.[拆分后单据编号])) AS SumQty2 from #2 AS a)
SELECT b.[单据编号],b.[物料编号],b.[拆分后单据编号],a.批号,CASE WHEN a.SumQty1>b.SumQty2 THEN b.SumQty2 ELSE a.SumQty1 END-CASE WHEN b.SumQty2 - b.数量>a.SumQty1 - a.数量 THEN b.SumQty2 - b.数量 ELSE a.SumQty1 - a.数量 END AS 扣减数量
FROM a
INNER JOIN b ON a.物料编号 = b.物料编号
AND a.SumQty1 > b.SumQty2 - b.数量
AND b.SumQty2 > a.SumQty1 - a.数量
ORDER BY 1;
/*
单据编号 物料编号 拆分后单据编号 批号 扣减数量
KMR16004350 CTN2006164D-/36R1 KMR16004350 SC160218-06 67
KMR16004350 CTN2006164D-/36R1 KMR16004350-1 SC160394-06 56
KMR16004350 CTN2006164D-/36R1 KMR16004350-1 SC160407-05 34
KMR16004350 CTN2006164D-/36R1 KMR16004350-1 SC160416-07 48
KMR16004350 CTN2006165D-/36R KMR16004350 SC160218-07 23
KMR16004350 CTN2006165D-/36R KMR16004350 SC160394-07 56
KMR16004350 CTN2006165D-/36R KMR16004350 SC160407-06 34
KMR16004350 CTN2006165D-/36R KMR16004350 SC160410-01 5
KMR16004350 CTN2006165D-/36R KMR16004350 SC160416-08 48
KMR16004681 CTN2007131A-/2 KMR16004681-1 SC160218-11 225
KMR16004681 CTN2007131A-/2 KMR16004681-2 SC160394-10 100
KMR16006465 CNR2006167A-/6R1 KMR16006465 SC160416-12 228
KMR16006465 CNR2006167A-/6R1 KMR16006465-1 SC160416-12 272
KMR16006465 CNR2006167A-/6R1 KMR16006465-2 SC160416-12 220
KMR16006465 CNR2006167A-/6R1 KMR16006465-3 SC160548-05 480
KMR16006465 CTN2006167A-6/24R3 KMR16006465 SC160416-12 57
KMR16006465 CTN2006167A-6/24R3 KMR16006465-1 SC160416-12 68
KMR16006465 CTN2006167A-6/24R3 KMR16006465-2 SC160416-12 55
KMR16006465 CTN2006167A-6/24R3 KMR16006465-3 SC160548-05 120
*/
;WITH cte_1 AS (
SELECT 单据编号,
物料编号,
SUM(a.数量) AS 总数量
FROM #mainorder a
GROUP BY 单据编号,物料编号
),
cte_2 AS (
-- 开始
SELECT a.单据编号,
a.物料编号,
a.批号,
CASE WHEN b.数量 - a.数量 > 0
THEN a.数量
ELSE b.数量
END AS 数量,
b.拆分后单据编号,
b.数量 - a.数量 AS 差值,
c.总数量 - (CASE WHEN b.数量 - a.数量 > 0
THEN a.数量
ELSE b.数量
END) AS 剩余数量
FROM #mainorder a
JOIN #suborder b
ON b.单据编号 = a.单据编号
AND b.物料编号 = a.物料编号
AND NOT EXISTS (SELECT 1 -- 第一条sub
FROM #suborder x
WHERE x.单据编号 = b.单据编号
AND x.物料编号 = b.物料编号
AND x.拆分后单据编号 < b.拆分后单据编号)
JOIN cte_1 c
ON c.单据编号 = a.单据编号
AND c.物料编号 = a.物料编号
WHERE NOT EXISTS (SELECT 1 -- 第一条main
FROM #mainorder x
WHERE x.单据编号 = a.单据编号
AND x.物料编号 = a.物料编号
AND x.批号 < a.批号)
UNION ALL -- 上个批号没分完(差值 > 0)
SELECT a.单据编号,
a.物料编号,
b.批号,
CASE WHEN b.数量 - a.数量 > 0
THEN a.数量
ELSE b.数量
END AS 数量,
a.拆分后单据编号,
a.差值 - b.数量 AS 差值,
a.剩余数量 - (CASE WHEN b.数量 - a.数量 > 0
THEN a.数量
ELSE b.数量
END) AS 剩余数量
FROM cte_2 a
JOIN #mainorder b
ON b.单据编号 = a.单据编号
AND b.物料编号 = a.物料编号
AND b.批号 > a.批号
AND NOT EXISTS (SELECT 1 -- 批号更大的main第一条
FROM dbo.#mainorder x
WHERE x.单据编号 = b.单据编号
AND x.物料编号 = b.物料编号
AND x.批号 > a.批号
AND x.批号 < b.批号)
WHERE a.差值 > 0
AND a.剩余数量 > 0
UNION ALL -- 上个批号不够分(差值 < 0)
SELECT a.单据编号,
a.物料编号,
a.批号,
CASE WHEN b.数量 + a.差值 > 0
THEN Abs(a.差值)
ELSE b.数量
END AS 数量,
b.拆分后单据编号,
b.数量 + a.差值 AS 差值,
a.剩余数量 - (CASE WHEN b.数量 + a.差值 > 0
THEN a.差值
ELSE b.数量
END) AS 剩余数量
FROM cte_2 a
JOIN #suborder b
ON b.单据编号 = a.单据编号
AND b.物料编号 = a.物料编号
AND b.拆分后单据编号 > a.拆分后单据编号
AND NOT EXISTS (SELECT 1 -- 拆分后单据编号更大的sub第一条
FROM dbo.#suborder x
WHERE x.单据编号 = b.单据编号
AND x.物料编号 = b.物料编号
AND x.拆分后单据编号 > a.拆分后单据编号
AND x.拆分后单据编号 < b.拆分后单据编号)
WHERE a.差值 < 0
AND a.剩余数量 > 0)
SELECT a.单据编号,
a.物料编号,
a.拆分后单据编号,
a.批号,
a.数量
FROM cte_2 a
ORDER BY a.单据编号,
a.物料编号,
a.批号,
a.拆分后单据编号
use Tempdb
go
--> --> 中国风(Roy)生成測試數據
if not object_id(N'Tempdb..#1') is null
drop table #1
Go
Create table #1([单据编号] nvarchar(31),[物料编号] nvarchar(38),[批号] nvarchar(31),[数量] int)
Insert #1
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160218-06',67 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160394-06',56 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160407-05',34 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'SC160416-07',48 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160218-07',23 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160394-07',56 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160407-06',34 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160410-01',5 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'SC160416-08',48 union all
select N'KMR16004681',N'CTN2007131A-/2',N'SC160218-11',225 union all
select N'KMR16004681',N'CTN2007131A-/2',N'SC160394-10',100 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'SC160416-12',720 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'SC160548-05',480 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'SC160416-12',180 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'SC160548-05',120
Go
--> --> 中国风(Roy)生成測試數據
if not object_id(N'Tempdb..#2') is null
drop table #2
Go
Create table #2([单据编号] nvarchar(31),[物料编号] nvarchar(38),[拆分后单据编号] nvarchar(33),[数量] int)
Insert #2
select N'KMR16004350',N'CTN2006164D-/36R1',N'KMR16004350',67 union all
select N'KMR16004350',N'CTN2006164D-/36R1',N'KMR16004350-1',138 union all
select N'KMR16004350',N'CTN2006165D-/36R',N'KMR16004350',166 union all
select N'KMR16004681',N'CTN2007131A-/2',N'KMR16004681-1',225 union all
select N'KMR16004681',N'CTN2007131A-/2',N'KMR16004681-2',100 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465',228 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465-1',272 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465-2',220 union all
select N'KMR16006465',N'CNR2006167A-/6R1',N'KMR16006465-3',480 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465',57 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465-1',68 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465-2',55 union all
select N'KMR16006465',N'CTN2006167A-6/24R3',N'KMR16006465-3',120
Go
;WITH a
AS
(SELECT *,SUM([数量])OVER(PARTITION BY [物料编号] ORDER BY [单据编号],[批号] ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS SumQty1 from #1)
,b AS
(SELECT *,SUM([数量])OVER(PARTITION BY [物料编号] ORDER BY [单据编号],[拆分后单据编号] ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS SumQty2 from #2)
SELECT b.[单据编号],b.[物料编号],b.[拆分后单据编号],a.批号,CASE WHEN a.SumQty1>b.SumQty2 THEN b.SumQty2 ELSE a.SumQty1 END-CASE WHEN b.SumQty2 - b.数量>a.SumQty1 - a.数量 THEN b.SumQty2 - b.数量 ELSE a.SumQty1 - a.数量 END AS 扣减数量
FROM a
INNER JOIN b ON a.物料编号 = b.物料编号
AND a.SumQty1 > b.SumQty2 - b.数量
AND b.SumQty2 > a.SumQty1 - a.数量
ORDER BY 1;
/*
单据编号 物料编号 拆分后单据编号 批号 扣减数量
KMR16004350 CTN2006164D-/36R1 KMR16004350 SC160218-06 67
KMR16004350 CTN2006164D-/36R1 KMR16004350-1 SC160394-06 56
KMR16004350 CTN2006164D-/36R1 KMR16004350-1 SC160407-05 34
KMR16004350 CTN2006164D-/36R1 KMR16004350-1 SC160416-07 48
KMR16004350 CTN2006165D-/36R KMR16004350 SC160218-07 23
KMR16004350 CTN2006165D-/36R KMR16004350 SC160394-07 56
KMR16004350 CTN2006165D-/36R KMR16004350 SC160407-06 34
KMR16004350 CTN2006165D-/36R KMR16004350 SC160410-01 5
KMR16004350 CTN2006165D-/36R KMR16004350 SC160416-08 48
KMR16004681 CTN2007131A-/2 KMR16004681-1 SC160218-11 225
KMR16004681 CTN2007131A-/2 KMR16004681-2 SC160394-10 100
KMR16006465 CNR2006167A-/6R1 KMR16006465 SC160416-12 228
KMR16006465 CNR2006167A-/6R1 KMR16006465-1 SC160416-12 272
KMR16006465 CNR2006167A-/6R1 KMR16006465-2 SC160416-12 220
KMR16006465 CNR2006167A-/6R1 KMR16006465-3 SC160548-05 480
KMR16006465 CTN2006167A-6/24R3 KMR16006465 SC160416-12 57
KMR16006465 CTN2006167A-6/24R3 KMR16006465-1 SC160416-12 68
KMR16006465 CTN2006167A-6/24R3 KMR16006465-2 SC160416-12 55
KMR16006465 CTN2006167A-6/24R3 KMR16006465-3 SC160548-05 120
*/
use Tempdb
go
--> --> 中国风(Roy)生成測試數據
if not object_id(N'Tempdb..#1') is null
drop table #1
Go
Create table #1([单据编号] nvarchar(23),[物料编号] nvarchar(23),[批号] nvarchar(23),[数量] int)
Insert #1
select N'a01',N'a02',N'a31',100 union all
select N'a01',N'a02',N'a32',200
Go
--> --> 中国风(Roy)生成測試數據
if not object_id(N'Tempdb..#2') is null
drop table #2
Go
Create table #2([单据编号] nvarchar(23),[物料编号] nvarchar(23),[拆分后单据编号] nvarchar(24),[数量] int)
Insert #2
select N'a01',N'a02',N'a011',180 union all
select N'a01',N'a02',N'a012',120
Go
;WITH a
AS
(SELECT *,SUM([数量])OVER(PARTITION BY [物料编号] ORDER BY [批号] ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS SumQty1 from #1)
,b AS
(SELECT *,SUM([数量])OVER(PARTITION BY [物料编号] ORDER BY [拆分后单据编号] ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS SumQty2 from #2)
SELECT b.[单据编号],b.[物料编号],b.[拆分后单据编号],a.批号,CASE WHEN a.SumQty1>b.SumQty2 THEN b.SumQty2 ELSE a.SumQty1 END-CASE WHEN b.SumQty2 - b.数量>a.SumQty1 - a.数量 THEN b.SumQty2 - b.数量 ELSE a.SumQty1 - a.数量 END AS 扣减数量
FROM a
INNER JOIN b ON a.物料编号 = b.物料编号
AND a.SumQty1 > b.SumQty2 - b.数量
AND b.SumQty2 > a.SumQty1 - a.数量;
/*
单据编号 物料编号 拆分后单据编号 批号 扣减数量
a01 a02 a011 a31 100
a01 a02 a011 a32 80
a01 a02 a012 a32 120
*/
use tempdb
go
--> --> (Andy)生成測試數據
if not object_ID('Tempdb..MainOrder') is null
drop table MainOrder
if not object_ID('Tempdb..SubOrder') is null
drop table SubOrder
Go
Create table MainOrder([单据编号] nvarchar(3),[物料编号] nvarchar(3),[批号] nvarchar(3),[数量] int)
Insert MainOrder
select 'a01','a02','a31',100 union all --(MainOrder Vs MainOrder) 2行对2行 情况
select 'a01','a02','a32',200 union all
select 'b01','b01','b31',50 union all --(MainOrder Vs MainOrder)多行对2行 情况
select 'b01','b01','b32',150 union all
select 'b01','b01','b33',200 union all
select 'b01','b01','b34',100 union all
select 'c01','c01','c31',200 union all --(MainOrder Vs MainOrder)2行对多行 情况
select 'c01','c01','c32',100
go
Create table SubOrder([单据编号] nvarchar(3),[物料编号] nvarchar(3),[拆分后单据编号] nvarchar(4),[数量] int)
Insert SubOrder
select 'a01','a02','a011',180 union all
select 'a01','a02','a012',120 union all
select 'b01','b01','b011',30 union all
select 'b01','b01','b012',470 union all
select 'c01','c01','c011',50 union all
select 'c01','c01','c012',60 union all
select 'c01','c01','c013',190
go
Select * from MainOrder
Select * from SubOrder
;with cte_1 as (
select 单据编号,物料编号,sum(a.数量) as [总数量] from MainOrder a group by 单据编号,物料编号
),cte_2 as (
select a.单据编号,a.物料编号,a.批号,case when b.数量-a.数量>0 then a.数量 else b.数量 end as 数量,b.拆分后单据编号,b.数量-a.数量 as [差值] ,c.总数量-case when b.数量-a.数量>0 then a.数量 else b.数量 end as [剩余数量]
from MainOrder a
inner join SubOrder b on b.单据编号=a.单据编号 and b.物料编号=a.物料编号
and not exists(select 1 from dbo.SubOrder x where x.单据编号=b.单据编号 and x.物料编号=b.物料编号 and x.拆分后单据编号<b.拆分后单据编号)
inner join cte_1 c on c.单据编号=a.单据编号 and c.物料编号=a.物料编号
where not exists(select 1 from MainOrder x where x.单据编号=a.单据编号 and x.物料编号=a.物料编号 and x.批号<a.批号)
union all
select a.单据编号,a.物料编号,b.批号,case when b.数量-a.差值>0 then a.差值 else b.数量 end as 数量,a.拆分后单据编号,a.差值-b.数量 as [差值],a.剩余数量-case when b.数量-a.差值>0 then a.差值 else b.数量 end as [剩余数量]
from cte_2 a
inner join MainOrder b on b.单据编号=a.单据编号 and b.物料编号=a.物料编号 and b.批号>a.批号
and not exists(select 1 from dbo.MainOrder x where x.单据编号=b.单据编号 and x.物料编号=b.物料编号 and x.批号>a.批号 and x.批号<b.批号)
where a.差值>0 and a.剩余数量>0
union all
select a.单据编号,a.物料编号,a.批号,case when b.数量+a.差值>0 then abs(a.差值) else b.数量 end as 数量,b.拆分后单据编号,b.数量+a.差值 as [差值],a.剩余数量-case when b.数量+a.差值>0 then a.差值 else b.数量 end as [剩余数量]
from cte_2 a
inner join SubOrder b on b.单据编号=a.单据编号 and b.物料编号=a.物料编号 and b.拆分后单据编号>a.拆分后单据编号
and not exists(select 1 from dbo.SubOrder x where x.单据编号=b.单据编号 and x.物料编号=b.物料编号 and x.拆分后单据编号>a.拆分后单据编号 and x.拆分后单据编号<b.拆分后单据编号)
where a.差值<0 and a.剩余数量>0
)
select a.单据编号,a.物料编号,a.拆分后单据编号,a.批号,a.数量 from cte_2 a order by a.单据编号,a.物料编号,a.批号,a.拆分后单据编号
/*
表三
单据编号 物料编号 拆分后单据编号 批号 数量
---- ---- ------- ---- -----------
a01 a02 a011 a31 100
a01 a02 a011 a32 80
a01 a02 a012 a32 120
b01 b01 b011 b31 30
b01 b01 b012 b31 20
b01 b01 b012 b32 150
b01 b01 b012 b33 200
b01 b01 b012 b34 100
c01 c01 c011 c31 50
c01 c01 c012 c31 60
c01 c01 c013 c31 90
c01 c01 c013 c32 100
*/
这里我列了三种情况,望楼主参考。