我有两张桌子:
第一个(金额):
amountid date amount
1 01.01.2011 100
2 02.01.2011 50
3 04.01.2011 200
4 10.01.2011 20
5 11.01.2011 5
第二个(期间):
periodid date
1 01.01.2011
2 03.01.2011
3 05.01.2011
我需要从第二张表中按时间分组第一张表,并且总和(金额):
这个例子的答案是:
01.01.2011 150
03.01.2011 200
05.01.2011 25
请帮我查询SQL。
答案 0 :(得分:3)
示例数据
declare @Amount table
(
amountid int,
[date] datetime,
amount int
)
declare @Period table
(
periodid int,
[date] datetime
)
insert into @Amount
select 1, '20110101', 100 union all
select 2, '20110102', 50 union all
select 3, '20110104', 200 union all
select 4, '20110110', 20 union all
select 5, '20110111', 5
insert into @Period
select 1, '20110101' union all
select 2, '20110103' union all
select 3, '20110105'
查询
select P.StartDate,
sum(A.amount) as amount
from (
select P1.[date] as StartDate,
coalesce((select min(P2.[date])
from @Period as P2
where P1.[date] < P2.[date]), '99991231') as endDate
from @Period as P1
) as P
inner join @Amount as A
on A.[date] >= P.StartDate and
A.[date] < P.EndDate
group by P.StartDate
答案 1 :(得分:1)
计算期间结束日期的查询是
select P1.periodid, P1.date as startdate, min(P2.date) as enddate
from period P1
left outer join period P2 on P2.date > P1.date
group by P1.periodid, P1.date
结果
PERIODID STARTDATE ENDDATE
1 2011-01-01 2011-01-03
2 2011-01-03 2011-01-05
3 2011-01-05 NULL
使用它可以汇总所有期间的所有金额,例如
select P.periodid, P.startdate, P.enddate, sum(A.amount) as sum
from (
select P1.periodid, P1.date as startdate, min(P2.date) as enddate
from period P1
left outer join period P2 on P2.date > P1.date
group by P1.periodid, P1.date
) P
left outer join amount A
on A.date >= P.startdate and (P.enddate is null or A.date < P.enddate)
group by P.periodid, P.startdate, P.enddate
结果
PERIODID STARTDATE ENDDATE SUM
1 2011-01-01 2011-01-03 150
2 2011-01-03 2011-01-05 200
3 2011-01-05 NULL 25
答案 2 :(得分:0)
create table #amount (
amountid int,
[date] datetime,
amount int
)
create table #period (
periodid int,
[date] datetime
)
delete from #amount
delete from #period
insert into #amount
values (1, {d '2011-01-01'}, 100),
(2, {d '2011-01-02'}, 50),
(3, {d '2011-01-04'}, 200),
(4, {d '2011-01-10'}, 20),
(5, {d '2011-01-11'}, 5)
insert into #period
values (1, {d '2011-01-01'}),
(2, {d '2011-01-03'}),
(3, {d '2011-01-05'})
select p.date, SUM(a.amount) as amount
from #period p inner join
(
select a.amountid, MAX(p.periodid) as periodid
from #amount a inner join
#period p on a.date >= p.date
group by a.amountid
) mp on p.periodid = mp.periodid inner join
#amount a on mp.amountid = a.amountid
group by p.date
如果您的期间表可以有结束日期,那肯定会更容易。
答案 3 :(得分:0)
现在我有来自其他论坛的sql-s:
declare @t table
( amountid int,date smalldatetime,amount int)
declare @p table (periodid int,date smalldatetime)
Insert into @t
Select 1,'2011-01-01', 100
union all
Select 2,'2011-01-02', 50
union all
Select 3,'2011-01-04', 200
union all
Select 4,'2011-01-10', 20
union all
Select 5,'2011-01-11', 5
Insert into @p
Select 1, '2011-01-01'
union all
Select 2, '2011-01-03'
union all
Select 3, '2011-01-05'
Select p.date, sum(t.amount) from
@P p
inner join
@t t on
p.date <= t.Date
where
not exists
( select top 1 1 from @p pp where pp.Date > p.Date and pp.Date < t.Date)
group by p.Date
如果我是对的,当我在我的服务器上“显示执行计划”时,这是最好的计划。
我是对的吗?