2016-04-28 32 views
1

我知道有幾個關於累計總數的答案。我已經嘗試過,並沒有找到解決我的問題的方法。獲取計數()其中created_date是累積和日期爲基礎

Here是一個sqlfiddle。

我們有兩個字段,EID和CREATE_TIME聯繫人表:

eid create_time 
991772 April, 21 2016 11:34:21 
989628 April, 17 2016 02:19:57 
985557 April, 04 2016 09:56:39 
981920 March, 30 2016 11:03:12 
981111 March, 30 2016 09:36:48 

我想我們的聯繫人數據庫的大小一起在每個月底在每個月選擇新的聯繫人數量月。按年份和月份的新聯繫人很簡單。 Contacts表在每個月底的大小我做了一些研究和found what looked to be a straight forwards method

set @csum = 0; 
select 
    year(c.create_time) as yr, 
    month(c.create_time) as mth, 
    count(c.eid) as new_contacts, 
    (@csum + count(c.eid)) as cumulative_contacts 
from 
    contacts c 
group by 
    yr, 
    mth 

運行,但讓我意外的結果。

如果我運行:

select count(*) from contacts where date(create_time) < current_date 

我得到的總記錄數表中的146

因此我使用@csum有146 2016年4月預計,最終排在我的查詢。它只有3?

我的目標是什麼字段cumulative_contacts: 對於記錄與例如2016年一月

select count(*) from contacts where date(create_time) < '2016-02-01'; 

而2月的記錄將有:

select count(*) from contacts where date(create_time) < '2016-03-01'; 

等等

+0

sqlfiddle鏈接不工作 – KaeL

回答

1

嘗試此,位從SQL修改的)

CREATE TABLE IF NOT EXISTS `contacts` (
    `eid` char(50) DEFAULT NULL, 
    `create_time` timestamp NULL DEFAULT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; 

INSERT INTO `contacts` (`eid`, `create_time`) VALUES 
('991772', '2016-04-21 11:34:21'), 
('989628', '2016-04-17 02:19:57'), 
('985557', '2016-04-04 09:56:39'), 
('981920', '2016-03-30 11:03:12'), 
('981111', '2016-03-30 09:36:48'); 

SET @csum = 0; 
SELECT t.*, @csum:=(@csum + new_contacts) AS cumulative_contacts 
FROM (
    SELECT YEAR(c.create_time) AS yr, MONTH(c.create_time) AS mth, COUNT(c.eid) AS new_contacts 
    FROM contacts c 
    GROUP BY yr, mth) t 

輸出結果是

| yr | mth | new_contacts | cumulative_contacts | 
------ ----- -------------- --------------------- 
| 2016 | 3 | 2   | 2     | 
| 2016 | 4 | 3   | 5     | 
+0

工作,謝謝。我按照年份,月份順序排序子查詢,否則這會失敗。再次感謝 –

1

試試這個:fiddele

這裏有一個 「大於或等於」加入,所以每個組「包含」所有以前的值。時代12部分,將洞比較轉換爲數月。我確實提供了這個解決方案,因爲它不依賴於MySql。 (可以在許多其它的DB來實現與minimun或沒有變化)

select dates.yr, dates.mth, dates.new_contacts, sum(NC.new_contacts) as cumulative_new_contacts 
from (
    select 
     year(c.create_time) as yr, 
     month(c.create_time) as mth, 
     count(c.eid) as new_contacts 
    from 
     contacts c 
    group by 
     year(c.create_time), 
     month(c.create_time) 
) as dates 
left join 
(
    select 
     year(c.create_time) as yr, 
     month(c.create_time) as mth, 
     count(c.eid) as new_contacts 
    from 
     contacts c 
    group by 
     year(c.create_time), 
     month(c.create_time) 
) as NC 
on dates.yr*12+dates.mth >= NC.yr*12+NC.mth 
group by 
    dates.yr, 
    dates.mth, 
    dates.new_contacts -- not needed by MySql, present here for other DBs compatibility 
order by 1,2 
+0

感謝您花時間回答。因爲我假設他們都做這個工作,所以我沒有特別好的理由與雷諾的回答一起。我不得不挑剔,發現裏諾的答案稍微可讀。我從來沒有見過像這樣的日期.yr * 12 + dates.mth> = NC.yr * 12 + NC.mth - times12部分..這是怎麼回事?只是好奇? –

+0

編輯回答。你可以upvote,如果它有幫助或教給你什麼 –

1

這個sql會得到累計和,並且非常高效。它首先爲每一行編號,然後將其用作累計和。

SELECT s1.yr, s1.mth, s1.new_contacts, s2.cummulative_contacts 
FROM 
    (SELECT 
     YEAR(create_time) AS yr, 
     MONTH(create_time) AS mth, 
     COUNT(eid) AS new_contacts, 
     MAX(eid) AS max_eid 
    FROM 
     contacts 
    GROUP BY 
     yr, 
     mth 
    ORDER BY create_time) s1 INNER JOIN 
     (SELECT eid, (@sum:[email protected]+1) AS cummulative_contacts 
    FROM 
     contacts INNER JOIN 
     (SELECT @sum := 0) r 
    ORDER BY create_time) s2 ON max_eid=s2.eid; 

--Result sample-- 
| yr | mth | new_contacts | cumulative_contacts | 
|------|-----|--------------|---------------------| 
| 2016 | 1 |   4 |     132 | 
| 2016 | 2 |   4 |     136 | 
| 2016 | 3 |   7 |     143 | 
| 2016 | 4 |   3 |     146 | 
+0

我想這會工作,如果我們假設聯繫數據庫和eid字段是有序的。感謝您花時間回答 –