2014-10-06 713 views
0

我有一個表,其中包含客戶名稱列,購買金額列和購買日期列。有一個簡單的方法,我可以找到第一次客戶每天花費多少錢?在SQL數據庫中查找元素的第一次出現

所以我

Name |  Purchase Amount | Date 
Joe   10    9/1/2014 
Tom   27    9/1/2014 
Dave   36    9/1/2014 
Tom   7     9/2/2014 
Diane   10    9/3/2014 
Larry   12    9/3/2014 
Dave   14    9/5/2014 
Jerry   16    9/6/2014 

而且我想是這樣

Date  |  Total first Time Purchase 
9/1/2014  73 
9/3/2014  22 
9/6/2014  16 

誰能幫我這個?

+2

您正在使用哪些DBMS? Postgres的?甲骨文? – 2014-10-06 21:06:14

回答

3

下面是標準的SQL,並適用於幾乎所有的DBMS

select date, 
     sum(purchaseamount) as total_first_time_purchase 
from (
    select date, 
      purchaseamount, 
      row_number() over (partition by name order by date) as rn 
    from the_table 
) t  
where rn = 1 
group by date; 

派生表(內部選擇)根據日期選擇所有「第一次」購買和外部聚合。

+1

我認爲你錯過了,分組依據日期 – Sagar 2014-10-06 21:40:05

+0

@Sagar : 當然是。謝謝,糾正。 – 2014-10-06 21:40:50

+0

謝謝!完美的作品! – user2900369 2014-10-07 01:00:21

1

這裏的兩個關鍵概念是aggregatessub-queries,您正在使用的dbms的細節可能會改變確切的實現,但基本概念是相同的。

  1. 對於每個名稱,確定他們的第一次約會
  2. 使用1的結果,發現每個人的首日申購金額
  3. 使用2的結果,總結的數額對於每一日期

在SQL Server中,它可能是這樣的:

select Date, [totalFirstTimePurchases] = sum(PurchaseAmount) 
from (
    select t.Date, t.PurchaseAmount, t.Name 
    from table1 t 
     join (
     select Name, [firstDate] = min(Date) 
     from table1 
     group by Name 
     ) f on t.Name=f.Name and t.Date=f.firstDate 
    ) ftp 
group by Date 
+0

'row_number'非常有用,但是這種格式幾乎適用於任何DBMS – 2014-10-06 21:18:29

+0

@PhilipKelley:以上只適用於SQL Server。但僅僅是因爲非標準列別名引用標識符 - 不是因爲窗口函數。 「幾乎每個DBMS」都支持窗口功能。 – 2014-10-06 21:36:34

+0

每個最近的數據庫管理系統,是的......但是,SO從舊系統的用戶(例如SQL 2000)中偶爾發佈帖子,這些用戶更有可能不指定他們正在使用的軟件版本,導致評論如「在我的系統上不起作用「。因此,當未指定版本時,我傾向於謹慎行事。 (你也是正確的:列別名 - 我更關注嵌套的子查詢。) – 2014-10-06 22:41:05

0

如果您正在使用SQL Server,你可以做到這一點的Wi或者sub-queries或CTE(Common Table Expressions)。由於sub-queries已經有答案,所以這裏是CTE版本。

首先,下面將找出每行那裏是第一次購買,然後獲得通過日期分組這些值的總和:

;WITH cte 
    AS (
     SELECT [Name] 
      ,PurchaseAmount 
      ,[date] 
      ,ROW_NUMBER() OVER (
       PARTITION BY [Name] ORDER BY [date] --start at 1 for each name at the earliest date and count up, reset every time the name changes 
       ) AS rn 
     FROM yourTableName 
     ) 
    SELECT [date] 
     ,sum(PurchaseAmount) AS TotalFirstTimePurchases 
    FROM cte 
    WHERE rn = 1 
    GROUP BY [date] 
+0

CTE對於SQL Server來說並不是特別的(事實上SQL Server對於遊戲來說很晚) – 2014-10-06 21:24:05

+0

也許,但是這個row_number語法在許多DBMS中是不同的我相信 – jimdrang 2014-10-06 21:31:20

+0

幾乎所有那些支持窗口函數的DBMS實際上都堅持SQL標準(並非所有的選項都支持所有選項,但語法總是相同的) – 2014-10-06 21:35:15

相關問題