我有以下数据:
UniqueID SenderID EntryID Date
1 1 1 2015-09-17
2 1 1 2015-09-23
3 2 1 2015-09-17
4 2 1 2015-09-17
5 3 1 2015-09-17
6 4 1 2015-09-19
7 3 1 2015-09-20
我需要的是:
3 2015-09-17
4 2015-09-19
4 2015-09-20
4 2015-09-23
第一列是截至该日期的唯一总条目。因此,例如,发件人1和条目1的23/9上的条目不会增加总列数,因为17/9中存在重复。
我如何有效地理想这样做,而不加入与你最终得到的相同的表是非常大的查询,这是不切实际的。我在Postgres中用OVER()完成了类似的操作,但遗憾的是这在此设置中不可用。
我也可以在代码中执行此操作 - 但我又要在db系统之外进行计算,然后重新导入。对于数百万行,此过程需要数天,理想情况下只需要几小时。
答案 0 :(得分:1)
OVER
是大多数数据库中可用的ANSI标准功能。你在计算什么是用户的开始,你可以用累积的总和来做到这一点:
select startdate,
sum(count(*)) over (order by startdate) as CumulativeUniqueCount
from (select senderid, min(date) as startdate
from table t
group by senderid
) t
group by startdate
order by startdate;
这应该适用于任何支持窗口功能的数据库,例如Oracle,SQL Server 2012 +,Postgres,Teradata,DB2,Hive,Redshift,仅举几例。
编辑:
您需要left join
才能获取数据中的所有日期:
select d.date,
sum(count(d.date)) over (order by d.date) as CumulativeUniqueCount
from (select distinct date from table t) d left join
(select senderid, min(date) as startdate
from table t
group by senderid
) t
on t.startdate = d.date
group by d.date
order by d.date;
答案 1 :(得分:0)
感谢Gordon Linoff的基本查询。但是,对于不增加累计总和的日期,它不会返回行。
要获取这些额外的行,您需要包含一个额外的子查询,列出表中的所有不同日期。然后你离开加入Gordon的查询+一些小调整以获得理想的结果:
select d.SomeDate,
sum(count(t.SenderId)) over (order by d.SomeDate)
from (select distinct SomeDate
from SomeTable) d
left join (select SenderId, min(somedate) as MinDate
from SomeTable
group by SenderId) t
on d.SomeDate = t.MinDate
group by d.SomeDate
order by d.SomeDate;