我试图弄清楚如何通过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 MONTH
的{{1}}。
例如:如果my_ftp_server在2014-11-10更新,那么NOW()
将成为2014-12-10 - 这将使expires
的WHERE子句从2014-11返回日期-16至2014-12-15 - 实际上是NEXT结算月份。
因此,我需要能够获得当前的结算周期。
大声思考一下......如果DATEDIFF(过期,NOW())大于INTERVAL 1 MONTH,那么可以选择WHERE date BETWEEN(DATE_ADD(DATE_SUB(expires, INTERVAL 1 MONTH), INTERVAL 1 DAY) AND NOW()
到期时的流量WHERE date > DATE_SUB(expires, INTERVAL 2 MONTH) - but if the difference between NOW() and
WHERE date> DATE_SUB(到期,间隔1个月)`
答案 0 :(得分:0)
您正在使用一个数据项expires
来表示两个不同的信息,尽管它们在大多数情况下是相同的,但CAN不同。
如果没有歧义,你不能这样做。
您必须使用不同的字段存储它们,一个用于表示结算周期,另一个用于表示付款到期日期。他们在“大部分时间”都是相同的这一事实并不重要。它们代表完全不同的数据项。
如果过期总是在结算周期结束时发生,并且该周期不能为客户改变,则可以通过仅存储到期月/年来节省几个字节,但我不认为这是值得的努力,如果需求发生变化,会更加脆弱。
为结算周期添加第二列。