Sql server 一列上的聚合函数,另一列上的group by,使第三列不受影响

Sql server 一列上的聚合函数,另一列上的group by,使第三列不受影响,sql-server,group-by,aggregate-functions,Sql Server,Group By,Aggregate Functions,我觉得这不是一个太坏的问题,但我一直在寻找一个解决方案,一天中的大部分时间都没有用。我见过很多似乎对我没有帮助的其他解决方案是获取非唯一值的列以及group by和AGGRATE函数 问题 我有一份历史数据表,如下所示: ID | source | value | date ---+--------+-------+----------- 1 | 12 | 10 | 2016-11-16 2 | 12 | 20 | 2015-11-16 3 | 12 |

我觉得这不是一个太坏的问题,但我一直在寻找一个解决方案,一天中的大部分时间都没有用。我见过很多似乎对我没有帮助的其他解决方案是获取非唯一值的列以及group by和AGGRATE函数

问题

我有一份历史数据表,如下所示:

ID | source | value | date
---+--------+-------+-----------
1  | 12     | 10    | 2016-11-16
2  | 12     | 20    | 2015-11-16
3  | 12     | 30    | 2014-11-16
4  | 13     | 40    | 2016-11-16
5  | 13     | 50    | 2015-11-16
6  | 13     | 60    | 2014-11-16
我试图在循环中的某个日期之前获取数据,以达到不同的范围,然后获取按源分组的值的总和。例如,获取30天前的所有记录,并使用每个记录的最新日期条目获取唯一来源的值之和

因此,第一步是删除日期不在范围内的条目,例如,一个简单的where date
ID | source | value | date
---+--------+-------+-----------
2  | 12     | 20    | 2015-11-16
3  | 12     | 30    | 2014-11-16
5  | 13     | 50    | 2015-11-16
6  | 13     | 60    | 2014-11-16
现在我的问题是找到一种按来源分组的方法,并取最大日期,然后汇总所有来源的结果。我们的想法是,我们不知道最后一个条目是什么时候,所以在指定的日期之前,我们获得所有记录,然后为每个唯一的源获取最新的条目,并将它们相加,以获得当时的总值

因此,下一步是使用最大日期按来源分组,结果是:

ID | source | value | date
---+--------+-------+-----------
2  | 12     | 20    | 2015-11-16
5  | 13     | 50    | 2015-11-16
最后一步是求和,然后重复这个过程,得到多个日期的和值,这样就得到了行

 value | date
-------+-----------
 70    | getdate() - 30
剩下的就用

我被困的地方

我正在尝试按源分组,并使用最大日期来获取每个唯一源的最新条目,但如果使用聚合函数或group by,则无法保留ID或value列以保留所选的最大行。完全有可能我只是误解了聚合函数的工作原理

迄今取得的进展

我到过的最好的地方是

with dataInDateRange as (
    select *
    from #historicalData hd
    where hd.date < getdate() - 30
)
select ???, max(date)
from dataInDateRange
group by source
但我不知道如何才能做到这一点,而不为每个源都有最大日期的行保留一个唯一的ID,这样我就可以返回并总结这些数字

感谢伟大的人们提供的任何帮助/指导/课程

使用排号

使用行号


看起来效果不错!我通过从行中选择不同的源进行检查,得到了相同数量的行。很好的解决方案,我会解释我的理解为我自己和任何其他可能结束在这里,任何更正将非常感激!第一次选择获取所需范围内的数据,然后我们对该数据进行处理,并按日期对每个源和订单进行一点分割,然后记录该小分组中的行号,以查看哪个是第一个,然后在rn中找到。是的,这是正确的。只需查看文档,顺便说一句,您可以将前两个查询合并到一个查询中。我只是为了便于阅读而把它们分开。看起来效果不错!我通过从行中选择不同的源进行检查,得到了相同数量的行。很好的解决方案,我会解释我的理解为我自己和任何其他可能结束在这里,任何更正将非常感激!第一次选择获取所需范围内的数据,然后我们对该数据进行处理,并按日期对每个源和订单进行一点分割,然后记录该小分组中的行号,以查看哪个是第一个,然后在rn中找到。是的,这是正确的。只需查看文档,顺便说一句,您可以将前两个查询合并到一个查询中。为了便于阅读,我把它们分开。
with dataInDateRange as (
    select *
    from #historicalData hd
    where hd.date < getdate() - 30
), rows as (
    select *, 
           row_number() over (partition by source 
                              order by date desc) as rn
    from dataInDateRange
)
SELECT *
FROM rows 
WHERE rn = 1