2016-11-11 2 views
4

Я начинаю изучать SQL Server и хочу просить идеи по этой проблеме. У меня есть система инвентаризации, которая имеет следующие таблицы:Получить баланс запасов в год

  1. Delivery Table (Stock_ID, Stock_Name, Quantity, Delivery_Date)
  2. 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

показать нам, что вы попробовали? потому что должен быть простым [** PIVOT. **] (https://technet.microsoft.com/es-es/library/ms177410 (v = sql.105) .aspx) –

ответ

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 
+0

Спасибо за помощь! Я немного подправил немного, но почти все поместилось именно так, как я этого хочу. Многому научился. Теперь я изучаю, как сделать динамический sql для части YEAR, но это было большой помощью. Спасибо огромное! :) – julie78ann

Смежные вопросы