2015-09-24 107 views
0

,我有以下數據計算不同的總計:隨着時間的推移

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的第23/9條和條目1的條目不會增加總列數,因爲從17/9有重複。

我怎樣纔能有效地理想做到這一點沒有因爲你最終得到的是一個非常大查詢,因此不實用在同一個表的加盟。我使用OVER()在Postgres中做了類似的事情,但不幸的是在這個設置中不可用。

我也可以在代碼中做到這一點 - 我有,但它又必須在數據庫系統之外進行計算,然後再導入。對於數百萬行,此過程需要數天,而且我理想情況下只需要幾個小時。

+3

*「我已經做了在Postgres類似的東西與OVER(),但遺憾的是,這是不可用在此設置」 *:您尚未提供此重要信息。你使用的是哪個數據庫?你的設置是什麼?你有什麼限制? – sstan

+0

在SenderID上使用子查詢和索引,EntryID是我能想到的最快的方法。 –

+0

我想成爲非數據庫特定的,因爲如果我能找到一個有用的功能,我很樂意移動到不同的平臺!我正在從MySQL遷移到PostgreSQL的OVER()功能,但如果有人說 - 「哦SQL服務器」可以做到這一點,那麼我會使用它。或者如果有一個我不知道的MySQL特性,那麼我會使用它。我不是一個特定於平臺的解決方案 - 我很靈活。 – Ukuser32

回答

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

這很棒,我會將它標記爲答案,但它只返回所需結果集中的前2行而不是4。 – Ukuser32

0

感謝戈登·利諾夫的基本查詢。但是,它不會返回不增加累計和的日期的行。

要獲得那些額外的行,您需要包含一個額外的子查詢,該子查詢列出表中所有不同的日期。然後你留下戈登的查詢+一些小的調整,加入以獲得期望的結果:

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; 
相關問題