我一直致力于CTE,它将根据某些工作项有效地创建发票行。给出:
Create table JobLines (line int, code varchar(10), qty decimal(9,2))
go
insert into JobLines values (1, '2222A', 1)
insert into JobLines values (2, '2222B', 3)
insert into JobLines values (3, '2222A', -1)
insert into JobLines values (4, '2222C', 2)
insert into JobLines values (5, '2222D', 1)
insert into JobLines values (6, '2222B', -1)
insert into JobLines values (7, '2222A', 2)
insert into JobLines values (8, '2222B', -1)
insert into JobLines values (9,'2222A', -1)
go
在匹配代码之前,从正线减去每条负线。
Line Code Quantity
1 222A 0
2 222B 1
4 222C 2
5 222D 1
7 222A 1
第1行 - 0(第3行减去)
第2 - 1行(减去第6和第8行)
第4行 - 没有变化。
第5行 - 没有变化。
第7 - 1行(第9行减去)。
我几次接近。主要问题是我无法获得第2行或第7行的预期结果,因为我无法有效地将需要减去的2行组合在一起。
我的方法是尝试迭代正线,为每个线提取负线。
我正在处理的示例代码:
;with cte_positive_rows as (select line, code, qty
,row_number() over (partition by code order by line) code_instance
,row_number() over (order by line) row_sequence
from jobLines
where qty > 0
)
,cte_negative_rows as (
select line, code, qty
,row_number() over (partition by code order by line) code_instance
,row_number() over (order by line) row_sequence
from jobLines
where qty < 0
)
,cte_iterator as(
--base case - start with line 1 from cte_postive_rows...
select min(base.line) line, base.code
,cast(sum(base.qty + neg.qty) as decimal(9,2)) total_qty
,base.code_instance
,base.row_sequence, base.row_sequence + 1 as next_row
from cte_positive_rows base
inner join cte_negative_rows neg
on
neg.row_sequence = base.row_sequence
and neg.code_instance = base.code_instance
where base.row_sequence = 1
group by base.code, base.code_instance, base.row_sequence
union all
--iterative case - each line..
-- the iterative case should returns all the rows that needed modifying
select row.line, row.code
,cast(row.qty + neg.qty as decimal(9,2)) qty, row.code_instance
,row.row_sequence
,row.row_sequence + 1 as next_row
from cte_positive_rows row
inner join cte_negative_rows neg
on
neg.row_sequence = row.row_sequence
and neg.code_instance = row.code_instance
inner join cte_iterator cte
on row.row_sequence = cte.next_row
)
-- get all the modified and non-modifed rows with joins
select pos.line, pos.code, pos.qty, pos.code_instance, pos.row_sequence
from cte_positive_rows pos
left outer join cte_iterator i
on pos.row_sequence = i.row_sequence
where i.row_sequence IS NULL
union all
select line, code, total_qty, code_instance, row_sequence from cte_iterator
order by row_sequence
不完全出现,结果如上:
1 2222A 0.00 1 1
2 2222B 2.00 1 2
4 2222C 2.00 1 3
5 2222D 1.00 1 4
7 2222A 2.00 2 5
我的梦想可能吗?!
答案 0 :(得分:1)
我不确定我是否完全理解您的要求,但这似乎可以满足您的需求:
select line, code, qty + isnull((
-- get the sum of all negative values...
select sum(j1.qty)
from JobLines j1
where
-- ...for the same code, but with a higher line number...
j1.code = PositiveLines.code and
j1.line > PositiveLines.line and
j1.qty < 0 and
-- ...where there is no positive value on a previous line
not exists (
select *
from JobLines
where
code = j1.code and
qty > 0 and
line > j1.line)
),0)
from
(
select
line, code, qty
from
JobLines
where
qty > 0
) PositiveLines