2014-10-28 41 views
0

我想弄清楚如何通過MySQL進行一些流量統計,我可以分成計費月份。計算流量統計的計費週期

我有一個表(traffic_logs)有:

日期| ip |入站|出站| last_updated

這會得到填充/更新以提供日常計數。

我有,有一個服務表:

SERVICE_NAME |過期| IPADDR

我目前使用的查詢,如:

SELECT SUM(inbound) AS traffic_in, SUM(outbound) AS traffic_out 
FROM services 
JOIN traffic_logs ON services.ip = traffic_logs.ip 
GROUP BY ip 
ORDER BY service_name; 

當我陷入的是,我想找到當前的結算月份的流量。

實施例的數據集:

 
traffic_logs table: 
+---------------+------------+------------+------------+---------------------+ 
|  ip  | date | inbound | outbound | last_updated  | 
+---------------+------------+------------+------------+---------------------+ 
| 192.168.1.100 | 2014-10-08 | 40372536 | 454591053 | 2014-10-08 23:55:03 | 
| 192.168.1.100 | 2014-10-09 | 22275659 | 241704264 | 2014-10-09 23:55:03 | 
| 192.168.1.100 | 2014-10-10 | 23481329 | 350904975 | 2014-10-10 23:55:03 | 
| 192.168.1.100 | 2014-10-11 | 28148019 | 177964416 | 2014-10-11 23:55:04 | 
| 192.168.1.100 | 2014-10-12 | 46099322 | 1383179073 | 2014-10-12 23:55:05 | 
| 192.168.1.100 | 2014-10-13 | 30171788 | 177338415 | 2014-10-13 23:55:06 | 
| 192.168.1.100 | 2014-10-14 | 22821090 | 260455364 | 2014-10-14 23:55:07 | 
| 192.168.1.100 | 2014-10-15 | 30049347 | 206231505 | 2014-10-15 23:55:07 | 
| 192.168.1.100 | 2014-10-16 | 33703952 | 413556561 | 2014-10-16 23:55:09 | 
| 192.168.1.100 | 2014-10-17 | 32386602 | 533711743 | 2014-10-17 23:55:10 | 
| 192.168.1.100 | 2014-10-18 | 34650714 | 576704272 | 2014-10-18 23:55:10 | 
| 192.168.1.100 | 2014-10-19 | 41040926 | 636292627 | 2014-10-19 23:55:10 | 
| 192.168.1.100 | 2014-10-20 | 40022284 | 542582298 | 2014-10-20 23:55:12 | 
| 192.168.1.100 | 2014-10-21 | 98535882 | 336734189 | 2014-10-21 23:55:12 | 
| 192.168.1.100 | 2014-10-22 | 41569882 | 292757699 | 2014-10-22 23:55:13 | 
| 192.168.1.100 | 2014-10-23 | 2147483647 | 934724220 | 2014-10-23 23:55:01 | 
| 192.168.1.100 | 2014-10-24 | 2147483647 | 462654543 | 2014-10-24 23:55:01 | 
| 192.168.1.100 | 2014-10-25 | 312027896 | 321416702 | 2014-10-25 23:55:01 | 
| 192.168.1.100 | 2014-10-26 | 34953533 | 341663241 | 2014-10-26 23:55:03 | 
| 192.168.1.100 | 2014-10-27 | 34335294 | 236423425 | 2014-10-27 23:55:03 | 
| 192.168.1.100 | 2014-10-28 | 34919816 | 492949009 | 2014-10-28 16:00:03 | 
+---------------+------------+------------+------------+---------------------+ 
 
services table: 
+---------------+------------+---------------+ 
| service_name | expires |  ip  | 
+---------------+------------+---------------+ 
| my_web_server | 2014-11-29 | 192.168.1.100 | 
| my_ftp_server | 2014-11-15 | 192.168.1.101 | 
+---------------+------------+---------------+ 

當服務被更新,它被更新爲expires=DATE_ADD(expires, INTERVAL 1 MONTH)

現在我正在嘗試計算當月結算週期內使用的流量。對於以上兩個例子的計費週期將是:

 
my_web_server: 
    2014-10-30 -> 2014-11-29 
    2014-09-30 -> 2014-10-29 
    2014-08-30 -> 2014-09-29 

my_ftp_server: 
    2014-10-16 -> 2014-11-15 
    2014-09-16 -> 2014-10-15 
    2014-08-16 -> 2014-09-15 

當我得到WHERE date BETWEEN(DATE_ADD(DATE_SUB(expires, INTERVAL 1 MONTH), INTERVAL 1 DAY) AND NOW()交通是一個月的時間內,一切都很好。

產品在到期前已被更新時會出現問題。這意味着expires大於INTERVAL 1 MONTHNOW()

例如:如果my_ftp_server在2014年11月10日更新,則expires將變爲2014-12-10 - 這將使WHERE date BETWEEN(DATE_ADD(DATE_SUB(expires, INTERVAL 1 MONTH), INTERVAL 1 DAY) AND NOW()的WHERE子句返回2014-11-16至2014-12年的日期 - 15 - 這實際上是下一個計費月份。

因此,我需要能夠獲得當前的結算週期。如果DATEDIFF(過期,NOW())大於INTERVAL 1 MONTH,那麼可以選擇流量與WHERE date > DATE_SUB(expires, INTERVAL 2 MONTH) - but if the difference between NOW() and到期is less than INTERVAL 1 MONTH, then I could use WHERE date> DATE_SUB(過期,INTERVAL 1個月) `

+0

沒有足夠的信息。什麼是帳單月份?所有客戶都一樣嗎?這聽起來像你的系統設計不完整。您必須更好地定義結算月的構成,如果是每個客戶,那麼您需要在'services'表中定義與當前到期日截然不同的月份邊界中的另一列。注意邊界條件。如果月份邊界是31號,那麼月份會有幾天發生什麼呢? – 2014-10-28 00:24:38

+0

這段時間總是一個月 - 每個產品都不相同。 expires字段始終是結算週期的最後一天。因此,DATE_SUB(到期,INTERVAL 1 MONTH)是最新的結算週期。 MySQL似乎在這方面處理日期非常好。 1月的最後一天將在2月的最後一天根據日期操作 - 它做適當的閏年等計算... 正如我所提到的 - 當NOW介於DATE_SUB(過期,INTERVAL 1月)和NOW()是事情破裂的地方。 – 2014-10-28 00:28:54

+0

@StevenHigh。 。 。您的問題可以通過樣本數據和預期結果更容易理解。 – 2014-10-28 00:55:52

回答

0

您正在使用一個數據項expires來表示兩個不同的信息,儘管它們大多數時間都是相同的,但CAN會有所不同。

你不能這樣做,沒有歧義。

您必須使用不同的字段來存儲它們,一個用來表示結算週期,一個用來表示已付清的到期日期。他們在「大部分時間」都是一樣的事實並不重要。它們代表完全不同的數據項。

如果到期時間總是發生在結算週期結束時,並且客戶的週期不能改變,您可以通過僅存儲到期月/年來節省幾個字節,但我認爲這不值得如果需求發生變化,將會變得更加脆弱。

爲結算週期添加第二列。

+0

我聽到你在說什麼,但是似乎還需要更多的工作來需要一個單獨的進程來計算如下內容:如果end_cycle = expires - interval 1 month,則SET end_cycle =在當前結算週期結束時過期以保持更新。 – 2014-10-28 00:58:39