我开始学习SQL Server,并希望就此问题提出想法。我有一个库存系统,其中包含以下表格:
Delivery Table (Stock_ID, Stock_Name, Quantity, Delivery_Date)
Disposal (Stock_ID, Stock_Name, Quantity, Disposal_Date)
示例Delivery
表:
Stock_ID Stock_Name Quantity Delivery_Date
0001 Plates 500 6/6/2015
0002 Glasses 1000 6/7/2015
0003 Plates 800 9/8/2016
0004 Spoon 200 9/8/2016
0005 Glasses 300 9/8/2016
0006 Plates 1000 10/1/2017
0007 Spoon 800 10/1/2017
0008 Glasses 200 10/1/2017
示例Disposal
表:
Stock_ID Stock_Name Quantity Delivery_Date
0001 Plates 20 9/6/2015
0002 Glasses 100 10/7/2015
0003 Plates 30 10/8/2016
0004 Spoon 20 12/8/2016
0005 Glasses 10 12/8/2016
0006 Plates 100 12/1/2017
0007 Spoon 20 12/1/2017
0008 Glasses 20 12/1/2017
基本上,我想获得每年的交割和处理摘要,以及所有股票的年终余额。
结果表有望看起来像:
Stock_Name: Plates
2015 2016 2017
1. Beginning Balance 0 480 1250
2. Delivery 500 800 1000
3. Disposal 20 30 100
4. Balance 480 1250 2150
我正在尝试PIVOT
和UNPIVOT
,但我似乎无法掌握如何使其发挥作用。请,任何帮助将不胜感激。谢谢!
答案 0 :(得分:1)
棘手的一点是做平衡魔法。这仍然需要多年的硬编码,您可以使用动态SQL来构建查询,使其适用于任意日期。可能有一种更简单的方法可以做到这一点,但这有效:
create table Delivery (Stock_ID int, Stock_Name varchar(50), Quantity int, Delivery_Date date);
create table Disposal (Stock_ID int, Stock_Name varchar(50), Quantity int, Disposal_Date date);
insert into delivery values(0001, 'Plates' , 500 , '6/6/2015');
insert into delivery values(0002, 'Glasses', 1000 , '6/7/2015');
insert into delivery values(0003, 'Plates' , 800 , '9/8/2016');
insert into delivery values(0004, 'Spoon' , 200 , '9/8/2016');
insert into delivery values(0005, 'Glasses', 300 , '9/8/2016');
insert into delivery values(0006, 'Plates' , 1000 , '10/1/2017');
insert into delivery values(0007, 'Spoon' , 800 , '10/1/2017');
insert into delivery values(0008, 'Glasses', 200 , '10/1/2017');
insert into disposal values(0001, 'Plates' , 20 , '9/6/2015');
insert into disposal values(0002, 'Glasses', 100, '10/7/2015');
insert into disposal values(0003, 'Plates' , 30 , '10/8/2016');
insert into disposal values(0004, 'Spoon' , 20 , '12/8/2016');
insert into disposal values(0005, 'Glasses', 10 , '12/8/2016');
insert into disposal values(0006, 'Plates' , 100, '12/1/2017');
insert into disposal values(0007, 'Spoon' , 20 , '12/1/2017');
insert into disposal values(0008, 'Glasses', 20 , '12/1/2017');
declare @stock varchar(50);
set @stock = 'Plates';
with transactions as
(
select Quantity,
Delivery_Date as D
from Delivery
where Stock_Name = @stock
union
select -Quantity,
Disposal_Date as D
from Disposal
where Stock_Name = @stock
),
ordered as
(
select *, ROW_NUMBER() over (order by D) rn
from transactions
),
running as
(
select *, sum(Quantity) over (order by rn rows unbounded preceding) running
from ordered
),
ordered2 as
(
select year(D) Y,
running as val,
row_number() over (partition by year(D) order by D) rnasc,
row_number() over (partition by year(D) order by D desc) rndesc
from running
),
data1 as
(
select 1 as ord, 'Beginning Balance' as row, o2.Y, isnull(b.val,0) as val
from ordered2 o2
outer apply (
select val from ordered2 i2 where i2.Y = o2.Y - 1 and rndesc =1
) b
where rnasc = 1
),
data2 as
(
select 2 as ord, 'Delivery' as row, year(Delivery_Date) as Y, sum(Quantity) as Quantity from Delivery where Stock_Name = @stock
group by year(Delivery_Date)
),
data3 as
(
select 3 as ord, 'Disposal' as row, year(Disposal_Date) as Y, sum(Quantity) as Quantity from Disposal where Stock_Name = @stock
group by year(Disposal_Date)
),
data4 as
(
select 4 as ord, 'Balance' as row, o2.Y, val
from ordered2 o2
where rndesc = 1
),
data as
(
select * from data1
union select * from data2
union select * from data3
union select * from data4
)
select row, [2015], [2016], [2017]
from
(
select ord, row, y, val
from data
) as s
pivot
(
sum(val)
for y IN ([2015],[2016],[2017])
) as p
order by ord