sql:随机周期汇总

时间:2011-10-19 07:52:33

标签: sql sql-server group-by sql-server-2000

我有两张桌子:

第一个(金额):

  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。

4 个答案:

答案 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

如果我是对的,当我在我的服务器上“显示执行计划”时,这是最好的计划。

我是对的吗?