选择每月最大日期SQL SERVER

时间:2013-01-23 13:34:21

标签: sql sql-server tsql select group-by

我有一个类似于Totals的数据库表,我试图选择每人每月的最大日期,以便我可以平均这个月的人均衡

 Date       Person     Balance
01-15-12       A        79
01-23-12       c        150
01-17-12       A        65
02-23-12       c        150
02-15-12       A        70
03-23-12       c        15
03-15-12       A        705
03-28-12       c        150
04-15-12       A        700
04-23-12       c        150

我将此表连接到一个名为#bal的临时表,其中只包含A B C等人 因此,对于每个月我只想要每人每月的最大行数,以便我可以将余额相加并找出每人每月的平均余额。

  create table #bal 
 (  
 person bigint,
 avgbal decimal,
 mxdate datetime

 )
  insert into #bal(person,avgbal,mxdate)
  select 
  b.person,
  (sum(s.BAL)/12) as avgbal,
  max(date) as mxdate 

  from #bal b
  inner join TOTALS s on (b.person=s.person)
  where DATE between '01-17-2012' and getdate()
  group by b.person

到目前为止有这样的事情,按日期分组,但我只想选择每月的最大日期。

4 个答案:

答案 0 :(得分:2)

我根据我根据上面的设置创建的一些样本数据生成了几个样本。我不确定你是想要每个月的最后一个值还是最大值,因为它们不一定相同,所以我写了两个基本查询:

declare @table table
(
date date,
person varchar(10),
balance int
)

insert into @table
select '01-15-12', 'A', 79
union all
select '01-23-12', 'c', 150
union all
select '01-17-12', 'A', 65
union all
select '02-23-12', 'c', 150
union all
select '02-15-12', 'A', 70
union all
select '03-23-12', 'c', 15
union all
select '03-15-12', 'A', 705
union all
select '03-28-12', 'c', 150
union all
select '04-15-12', 'A', 700
union all
select '04-23-12', 'c', 150;

-- Average of max balance in month
with maxMonth as
(
  select year = year(date)
    , month = month(date)
    , person, monthMaxBalanace = max(balance)
  from @table
  where date between '01-17-2012' and getdate()
  group by year(date), month(date), person
)
select person, maxInMonthAverage = avg(monthMaxBalanace)
from maxMonth
group by person;

或者,如果您需要在每个月使用 last 余额,则可以更改查询:

-- Average of last balance in month
with lastInMonth as
(
  select year = year(date)
    , month = month(date)
    , person, balance
    , monthRank = row_number() over (partition by year(date), month(date), person order by date desc)
  from @table
  where date between '01-17-2012' and getdate()
),
lastRows as
(
  select * from lastInMonth where monthRank = 1
)
select person, lastInMonthAverage = avg(balance)
from lastRows
group by person;

根据您的示例查询(即17-Jan及更高版本),结果是相同的,但如果您包含15日的值,则由于两个查询中的逻辑不同而略有不同。

enter image description here

答案 1 :(得分:1)

这将检索每月和每个人每月最后一天的行..

select V.[date]
  ,V.person
  ,V.balance
from (  select [person]
          ,[date]
          ,max([date]) over(partition by person,datediff(mm,0,[date])) as [max_date]
          ,balance
    from @table
)V
where V.[date]=V.max_date

这可以检索到期间所有月份的平均值

select V.person
,SUM(balance)/12 as avgbal_as_u_calc
,AVG(balance) as average_balance
from (  select [person]
          ,[date]
          ,max([date]) over(partition by person,datediff(mm,0,[date])) as [max_date]
          ,balance
    from @table
)V
where V.[date]=V.max_date
group by V.person

答案 2 :(得分:0)

你正在寻找这样的东西吗?查询可以解除分组以显示每个月的数据。在这里,我按每个用户每个月的最大日期取得余额,总结并给出年平均值。

查询:

select x.person, sum(p.balance) maxtotal,
sum(p.balance) /12 average
from (select max(date) mxdt,
      month(Date) as month,
      person
from person
group by month(Date), person) x
join person p
on p.person = x.person
and p.date = x.mxdt
group by x.person;

| PERSON | MAXTOTAL | AVERAGE |
-------------------------------
|      A |     1540 |     128 |
|      c |      600 |      50 |

答案 3 :(得分:-2)

这是Oracle查询。它不是基于您的表格。所有数据都可以随时使用。 内部查询将按月向您提供日期,例如01,02 ...如果这是你想要的,那么外部每月获得MAX值,我正确地理解了这个问题。您只需将日期转换为月份编号并按其分组。您可以将人员添加到分组中。我希望这会有所帮助:

SELECT curr_mo, MAX(some_val) 
  FROM
   (-- 10 weeks starting with '01-15-2012' --
     SELECT to_char(to_date('01-15-2012', 'mm-dd-yyyy')+LEVEL*7, 'mm') curr_mo 
      , MOD(LEVEL, 2)+3 some_val
       FROM dual
     CONNECT BY LEVEL <= 10 
   )
  GROUP BY curr_mo
 /

 Inner query output:

 CURR_MO    SOME_VAL
 -------------------
  01         4
  01         3
  02         4
  02         3
  .....

  Output - MAX per each mo:

  CURR_MO   MAX(SOME_VAL)
  ------------------------
  01         4
  02         4
  03         4
  ....