我正在尝试编写一个查询来报告在特定月份内部件的使用次数。例如,将二月作为报告月份。如果P1在2014-02-05之前安装在A1上,并且在2014-02-01至2014-02-05之间使用,那么我需要总结一下。此外,如果P1安装在A2上,那么我需要总结使用情况,直到2014-02-28。
| part | date_trans | transaction | unit |
---------------------------------------------
p1 2014-02-05 removed A1
p1 2014-02-07 installed A2
| unit | daily usage | date |
A1 3 2014-02-01
A1 2 2014-02-03
A2 2 2014-02-05
A2 4 2014-02-08
A2 2 2014-02-20
记录的通知
| unit | daily usage | date |
A2 2 2014-02-05
我们不需要考虑因为2014年2月2日未在A2上安装P1。
到目前为止,这是我的尝试..
SELECT
CASE
WHEN h.date_trans between '2014-01-31' and '2014-02-28' and transaction='removed' THEN...
END AS 'test'
FROM history h join acu on(acu.unit=h.unit)
WHERE h.part='P1'
答案 0 :(得分:0)
像这样。
/*
create table #t1 (part char(2), date_trans date, trans char(10), unit char(2))
go
insert #t1 values
('p1', '2014-02-05', 'removed' , 'A1'),
('p1', '2014-02-07' , 'installed', 'A2')
go
create table #t2 (unit char(2), usage int, dt date)
go
insert #t2 values
( 'A1', 3, '2014-02-01'),
( 'A1', 2, '2014-02-03'),
( 'A2', 2, '2014-02-05'),
( 'A2', 4, '2014-02-08'),
( 'A2', 2, '2014-02-20')
*/
declare @min date = '20140201', @max date = '20140228'
;with x as (
select *,
isnull(case trans when 'removed' then lag(date_trans) over(partition by part order by date_trans) else date_trans end, @min) as date_start,
isnull(case trans when 'installed' then lead(date_trans) over(partition by part order by date_trans) else date_trans end, @max) as date_end
from #t1
)
select #t2.unit, x.part, sum(#t2.usage)
from #t2
inner join x on #t2.dt between x.date_start and x.date_end
and x.unit = #t2.unit
group by #t2.unit, x.part
-- drop table #t1, #t2
以下是旧版(2012年之前)版本的查询:
;with x as (
select *, row_number() over(partition by part order by date_trans) as rn
from #t1
),
y as (
select x1.*,
case x1.trans when 'removed' then isnull(x2.date_trans, @min) else x1.date_trans end as date_start,
case x1.trans when 'installed' then isnull(x3.date_trans, @max) else x1.date_trans end as date_end
from x x1
left outer join x x2 on x1.rn = x2.rn+1
left outer join x x3 on x1.rn = x3.rn-1
)
select #t2.unit, y.part, sum(#t2.usage)
from #t2
inner join y on #t2.dt between y.date_start and y.date_end
and y.unit = #t2.unit
group by #t2.unit, y.part
答案 1 :(得分:0)
您可以使用CTE尝试以下查询:
with history_installed as
(select part,
case
when date_trans <= '2014-02-01' then '2014-02-01'
else date_trans
end date_trans
from history
where transaction = 'installed' and date_trans < '2014-03-01')
, history_removed as
(select part,
case
when date_trans >= '2014-02-28' then '2014-02-28'
else date_trans
end date_trans
from history
where transaction = 'removed' and date_trans >= '2014-02-01')
select acu.*
from acu
inner join history_installed on history_installed.date_trans <= acu.date
inner join history_removed on history_removed.date_trans >= acu.date