2016-12-05 47 views
0

我觉得这个问题不算太坏,但我一直在寻找一个大部分时间无法解决的问题。我见过很多其他解决方案似乎并不能帮助我获得不是唯一值的列以及group by和aggregate函数。在一列上聚合函数,在另一列上聚合函数,让第三列不受影响

问题

我有历史数据的表如下:

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 < getdate()-30例如获得:

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 

现在我的问题是找到一种方法来group by源,并采取max日期,然后对所有来源的结果进行总结。我们听到的想法是,我们不知道最后一次输入是什么时候,所以在指定日期之前我们会得到所有记录,然后为每个唯一的源采取最新的输入项,然后求和这些输入以获得当时的总值。

因此,下一步将使用日期的最大值,从而可以对组由源:

ID | source | value | date 
---+--------+-------+----------- 
2 | 12  | 20 | 2015-11-16 
5 | 13  | 50 | 2015-11-16 

然后在最后一步将是值相加,然后重复这个过程中得到多个日期的总和值,所以这将导致行

value | date 
-------+----------- 
70 | getdate() - 30 

其余的使用。

当我被困

我想GROUP BY source和使用的date最大,以获取最新的每一个独特的source项,但如果我使用聚合函数或group by ,那么我不能保留IDvalue列以坚持选定的最大行。这完全有可能,我只是误解了聚合函数的工作原理。

迄今取得的进展

我已经得到了最好的地方,却是一样的东西

with dataInDateRange as (
    select * 
    from #historicalData hd 
    where hd.date < getdate() - 30 
) 
select ???, max(date) 
from dataInDateRange 
group by source 

但我没有看到我怎么能做到这一点不以某种方式保存的唯一ID每个source的最大date的那一行,然后我可以回去总结这些数字。

谢谢你伟大的人民任何帮助/引导/教训

回答

2

使用row_number()

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 
+0

看起来行之有效!我通过做'从行中选择不同的源代码'来检查并获得相同数量的行。好的解决方案,我会解释我对自己和其他任何可能会在这里结束的理解,任何更正将不胜感激! 第一个select获取所需范围内的数据,然后我们对这些数据进行处理,并对每个'source'进行一些分割,然后对'date'进行排序,然后在该小分组内记录行号以查看哪一个是第一个,然后在'rn'中找到。 –

+1

是的,这是正确的。只需检查文档https://msdn.microsoft.com/es-es/library/ms186734.aspx, –

+1

顺便说一句,你可以合并前两个查询在一个单一的。我只是为了便于阅读而分开。 –