Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
选择SQL SERVER每月的最大日期_Sql_Sql Server_Tsql_Select_Group By - Fatal编程技术网

选择SQL SERVER每月的最大日期

选择SQL SERVER每月的最大日期,sql,sql-server,tsql,select,group-by,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 1

我有一个数据库表,看起来像这样,叫做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

到目前为止,我有这样一个按日期分组的示例,但我只想选择每月的最大天数。

我已经根据我根据上述集合创建的一些示例数据生成了几个示例。我不确定您想要的是每个月的最后一个值还是最大值,因为它们不一定相同,所以我为这两个都编写了基本查询:

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;
或者,如果您需要使用每个月的最后余额,您可以更改查询:

-- 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;
根据您的示例查询,即1月17日及以上,结果是相同的,但如果您包含15日的值,则由于两个查询中的逻辑不同,结果略有不同


你在找这样的东西吗?查询可以反分组以显示每月数据。。在这里,我取每个用户当月每个最大日期的余额,求和并给出年平均值

查询:

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 |

这是Oracle查询。它不是基于您的表。可以说,所有数据都在流动中。 内部查询将按月份编号为您提供日期,例如01、02。。。如果这是您想要的,并且我正确理解这个问题,则外部每月获得最大值。您只需将日期转换为月号并按其分组即可。您可以通过将人员添加到组中。我希望这有助于:

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
  ....

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

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条相同日期的记录吗?还可以修复SQL吗?上次查询中缺少SELECT语句。您正在创建的bal temp表甚至没有3列,而您的测试数据显示了3列。很难确切地知道你要去哪里。不,日期是different@ERead请看一下演示并发表评论,如果您需要任何其他更改,如果解决方案提供或不提供您所需的内容,请告诉我们。我不确定如何在我的SQL中实现此功能,总计表在哪里?我有bal作为临时人员表,我将其加入到人员总数表中,该表包含我在上面显示的值或余额和日期。我根据您在上面提供的数据表创建了此解决方案。你们也有总计表吗?我得到的印象是,您只有persons表date、person、bal,您希望得到每个人每月的最大日期之和,然后从中得到平均值…因此,每月最大余额的平均值选择每个月的最大余额,并将其相加,而不是平均值。对于每个人,第一个查询/结果集,在指定的日期范围内获取每个月的最大余额,然后对这些最大值进行平均。哦,是的,这很好,对不起,我很抱歉你的子查询,但在下面遗漏了它。你是在求和并获得平均值,所以我想这是对的,因为你的每月获得最大值工具-为了更清楚,我已经拆分了上面的代码。您应该能够将代码直接粘贴到查询窗口中,并将其用作您自己代码的基础。我猜竞争专家再次。。。我来这里是为了不得分。合作是关键,而不是相反。