Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
日期范围内的Mysql频率_Mysql_Sql - Fatal编程技术网

日期范围内的Mysql频率

日期范围内的Mysql频率,mysql,sql,Mysql,Sql,我有一个MySQL数据库: Date Customer_ID 我怎样才能把它变成: Customer_ID | Count_Visits_Past_Week | Count_Visits_Past_Month | Count_Visits_Past_90days | Count_Total 注意:计数\u总计=其他三个计数的总和 谢谢我想这会给你想要的 select customer_id, sum(case when splitter = 'week' then n

我有一个MySQL数据库:

Date     Customer_ID
我怎样才能把它变成:

Customer_ID | Count_Visits_Past_Week | Count_Visits_Past_Month | Count_Visits_Past_90days  | Count_Total
注意:
计数\u总计=其他三个计数的总和


谢谢

我想这会给你想要的

select customer_id,
       sum(case when splitter = 'week' then num_visits else 0 end) as visits_this_week,
       sum(case when splitter = 'month' then num_visits else 0 end) as visits_this_month,
       sum(case when splitter = '90days' then num_visits else 0 end) as visits_last_90days,
       sum(num_visits) as total
  from (select customer_id, 'week' as splitter, count(*) as num_visits
          from tbl
         where extract(week from date) = extract(week from sysdate())
           and extract(year from date) = extract(year from sysdate())
         group by customer_id
        union all
        select customer_id, 'month' as splitter, count(*) as num_visits
          from tbl
         where extract(month from date) = extract(month from sysdate())
           and extract(year from date) = extract(year from sysdate())
         group by customer_id
        union all
        select customer_id, '90days' as splitter, count(*) as num_visits
          from tbl
         where date between date_sub(sysdate(), interval 90 day) and
               sysdate()) x
 group by customer_id

sql FIDLE示例:

第一步是确定指定日期范围的分界点

这里有几个问题需要回答:您是否只想比较日期('yyyy-mm-dd')而忽略任何时间组件

所谓“过去一周”,是指过去七天内,还是指自上一个星期日至今,还是指从星期日到星期六的最后一整周

“上个月”是指上一个月,从第一个月到月底?或者,这是否意味着如果查询是在本月20日运行的,那么我们需要上个月20日到今天的日期?还是昨天

一旦我们知道相对于今天的日期开始和结束每个指定时段的时间点,我们就可以构建计算这些日期的表达式

例如,“过去的一周”可以表示为最近的七天期间:

DATE(NOW())-INTERVAL 1 WEEK    -thru-   DATE(NOW())
“过去一个月”可以表示为直到今天的前一个月的同一个“月日”(如17日):

DATE(NOW())-INTERVAL 1 MONTH   -thru-   DATE(NOW())
这实际上是第一步,确定每个指定时段的开始和结束日期


一旦我们有了它,我们就可以继续构建一个查询,该查询将获得每个时段内
date
列的行数

“技巧”是在查询的SELECT列表中的表达式中使用条件测试。如果该行要包含在“计数”中,我们将使用这些条件测试返回1,如果该行被排除,则返回0或NULL

我更喜欢使用
SUM()
aggregate函数来获取“count”。但是也可以使用
COUNT()
aggregate。(如果我们使用
COUNT()
,我们需要使用一个表达式,该表达式在要排除行时返回NULL。我更喜欢返回1或0;我认为这使调试更容易

下面是“count”查询的大致情况

SELECT t.Customer_Id
     , SUM(IF( <some_condition>  ,1,0) AS Count_something
     , SUM(IF( <other_condition> ,1,0) AS Count_something_else
  FROM mytable t
 GROUP BY t.Customer_Id
该查询不返回“count”,它只返回表达式的结果,这在测试中很有用。当然,我们要测试返回每个期间的开始和结束日期的表达式:

SELECT DATE(NOW()) - INTERVAL 1 WEEK  AS past_week_begin
     , DATE(NOW())                    AS past_week_end

使用这种方法,同一行可以通过一次查询和一次表传递包含在多个“计数”中

请注意,下面查询中的
SUM()
聚合中的表达式利用了一种方便的速记方式,作为布尔值计算的表达式将返回1(如果为真)、0(如果为假)或NULL

要使用计数聚合,我们需要确保被聚合的表达式在要“计数”行时返回非NULL,在将该行从计数中排除时返回NULL。因此,如果表达式返回的值为零,我们使用方便的NULLIF函数返回NULL

SELECT t.Customer_ID
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 WEEK  AND DATE(NOW()),0))
       AS Count_Visits_Past_Week
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 MONTH AND DATE(NOW()),0))
       AS Count_Visits_Past_Month
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 90 DAY  AND DATE(NOW()),0))
       AS Count_Visits_Past_90days
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 WEEK  AND DATE(NOW()),0))
     + COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 MONTH AND DATE(NOW()),0))
     + COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 90 DAY  AND DATE(NOW()),0))
       AS Count_Total
  FROM mytable t
 GROUP BY t.Customer_Id
注意:
NULLIF(a,b)
的一个方便的缩写,如果a为NULL,则返回b,否则返回a

返回Count\u Total有点奇怪,因为它有可能多次“计数”同一行……但是它返回的值应该与单个计数的总和相匹配。

当你说“过去的一周”和“过去的一个月”时,你是指与当前周相同的一周,与当前月相同的一周吗?
SELECT t.Customer_ID
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 WEEK  AND DATE(NOW()),0))
       AS Count_Visits_Past_Week
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 MONTH AND DATE(NOW()),0))
       AS Count_Visits_Past_Month
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 90 DAY  AND DATE(NOW()),0))
       AS Count_Visits_Past_90days
     , COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 WEEK  AND DATE(NOW()),0))
     + COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 1 MONTH AND DATE(NOW()),0))
     + COUNT(NULLIF( t.date BETWEEN DATE(NOW())-INTERVAL 90 DAY  AND DATE(NOW()),0))
       AS Count_Total
  FROM mytable t
 GROUP BY t.Customer_Id