如果我有以下数据结构,如下所示,其中按类别计算产品总数,以及计算的日期,我如何计算所有值之间的差异。
例如,商店ABC的Thing1差异为-4。但是,如果我的实际数据有更多的日期而不仅仅是这两个。因此,我需要计算产品的每个日期之间的差异,以及更广泛的范围,例如季度。这是使用SQL Server 2014
Store | Product | Total | Date |
ABC | Thing1 | 6 | 1-1-2013 |
ABC | Thing2 | 2 | 1-1-2013 |
XYZ | Thing1 | 4 | 1-1-2013 |
XYZ | Thing2 | 7 | 1-1-2013 |
ABC | Thing1 | 2 | 5-1-2013 |
ABC | Thing2 | 4 | 5-1-2013 |
XYZ | Thing1 | 3 | 5-1-2013 |
XYZ | Thing2 | 9 | 5-1-2013 |
答案 0 :(得分:1)
假设您使用的是SQL 2012或更高版本,则可以使用以下查询:
;with cte as (
select *
, LEAD(Total) over (partition by Store, Product order by Store, Product, Dt) NextTotal
from #t
)
select Store, Product, Dt, (NextTotal - Total) as Delta
from cte
where (NextTotal - Total) is not null
order by Dt, Store, Product
测试一下:
create table #t (Store varchar(10), Product varchar(10), Total int, Dt date)
insert into #t values
('ABC', 'Thing1', 6, '1-1-2013'),
('ABC', 'Thing2', 2, '1-1-2013'),
('XYZ', 'Thing1', 4, '1-1-2013'),
('XYZ', 'Thing2', 7, '1-1-2013'),
('ABC', 'Thing1', 2, '5-1-2013'),
('ABC', 'Thing2', 4, '5-1-2013'),
('XYZ', 'Thing1', 3, '5-1-2013'),
('XYZ', 'Thing2', 9, '5-1-2013')
<强>结果:强>
╔═══════╦═════════╦════════════╦═══════╗
║ Store ║ Product ║ Dt ║ Delta ║
╠═══════╬═════════╬════════════╬═══════╣
║ ABC ║ Thing1 ║ 2013-01-01 ║ -4 ║
║ ABC ║ Thing2 ║ 2013-01-01 ║ 2 ║
║ XYZ ║ Thing1 ║ 2013-01-01 ║ -1 ║
║ XYZ ║ Thing2 ║ 2013-01-01 ║ 2 ║
╚═══════╩═════════╩════════════╩═══════╝
如果帖子已回答问题,请“标记为答案”
答案 1 :(得分:1)
如果您没有SQL Server 2012(以及LEAD功能),这对您有用。
create table #Inventory
(
Store varchar(10),
Product varchar(10),
Total int,
DateCounted Date
)
insert into #Inventory values ('ABC', 'Thing1', 6, '2013-01-01')
insert into #Inventory values ('ABC', 'Thing2', 2, '2013-01-01')
insert into #Inventory values ('XYZ', 'Thing1', 4, '2013-01-01')
insert into #Inventory values ('XYZ', 'Thing2', 7, '2013-01-01')
insert into #Inventory values ('ABC', 'Thing1', 2, '2013-05-01')
insert into #Inventory values ('ABC', 'Thing2', 4, '2013-05-01')
insert into #Inventory values ('XYZ', 'Thing1', 3, '2013-05-01')
insert into #Inventory values ('XYZ', 'Thing2', 9, '2013-05-01')
;
with #InventoryChange as
(
select rownum = row_number() over
(
partition by Store, Product
order by Store, Product, DateCounted
), Store, Product, Total, DateCounted
from #Inventory
)
select a.*, b.Total - a.Total as Difference
from #InventoryChange a
left join #InventoryChange b on a.Store = b.Store and a.Product = b.Product and a.rownum = b.rownum - 1
我发现了这种技术here。
答案 2 :(得分:0)
如果差异是指基于日期的第一个和最后一个总计之间的差异,则一个方法使用row_number()
和条件聚合:
select store, product,
max(case when seqnum_asc = 1 then total end) as first_total
max(case when seqnum_desc = 1 then total end) as last_total,
(max(case when seqnum_desc = 1 then total end) -
max(case when seqnum_asc = 1 then total end)
) as diff
from (select t.*,
row_number() over (partition by store, product order by date) as seqnum_asc,
row_number() over (partition by store, product order by date desc) as seqnum_desc
from t
) t
where seqnum_asc = 1 or seqnum_desc = 1
group by store, product;
答案 3 :(得分:0)
WITH TEMP (Store , Product , Total , DT)
AS (
SELECT 'ABC' , 'Thing1' , 6 , '1-1-2013' from dual union all
SELECT 'ABC' , 'Thing2' , 2 , '1-1-2013' from dual union all
SELECT 'XYZ' , 'Thing1' , 4 , '1-1-2013' from dual union all
SELECT 'XYZ' , 'Thing2' , 7 , '1-1-2013' from dual union all
SELECT 'ABC' , 'Thing1' , 2 , '5-1-2013' from dual union all
SELECT 'ABC' , 'Thing2' , 4 , '5-1-2013' from dual union all
SELECT 'XYZ' , 'Thing1' , 3 , '5-1-2013' from dual union all
SELECT 'XYZ' , 'Thing2' , 9 , '5-1-2013' from dual
)
select Store, Product, max(DT),
min(TOTAL) keep (dense_rank FIRST order by DT desc) - min(TOTAL) keep (dense_rank LAST order by DT desc) as DIFF
from temp
group by Store, Product
;
输出:
STORE PRODUCT MAX(DT) DIFF
----- ------- -------- ----------
ABC Thing1 5-1-2013 -4
ABC Thing2 5-1-2013 2
XYZ Thing1 5-1-2013 -1
XYZ Thing2 5-1-2013 2