在sql中查找Period的计数

时间:2015-06-05 04:27:43

标签: mysql sql

我有一张桌子:

 user_id | order_date 
---------+------------
      12 | 2014-03-23
      12 | 2014-01-24
      14 | 2014-01-26
      16 | 2014-01-23
      15 | 2014-03-21
      20 | 2013-10-23
      13 | 2014-01-25
      16 | 2014-03-23
      13 | 2014-01-25
      14 | 2014-03-22

活跃用户是指过去12个月内登录过的用户。 需要输出为

Period | count of Active user
----------------------------
Oct-2013 - 1 
Jan-2014 - 5 
Mar-2014 - 10

2014年1月的价值 - 包括2014年10月的1记录和2014年1月的4个非重复记录)

5 个答案:

答案 0 :(得分:6)

您可以使用变量来计算活跃用户的总计:

SELECT Period,
       @total:=@total+cnt AS `Count of Active Users`
FROM (       
SELECT CONCAT(MONTHNAME(order_date), '-', YEAR(order_date)) AS Period,
       COUNT(DISTINCT user_id) AS cnt       
FROM mytable 
GROUP BY Period
ORDER BY YEAR(order_date), MONTH(order_date) ) t,
(SELECT @total:=0) AS var

子查询返回每月/每年不同活跃用户的数量。外部查询使用@total变量来计算活跃用户的运行总数'计数。

Fiddle Demo here

答案 1 :(得分:3)

我有两个问题可以解决这个问题。我不确定哪一个是最快的。检查他们的数据库:

SQL Fiddle

查询1

select per.yyyymm,
(select count(DISTINCT o.user_id) from orders o where o.order_date >= 
(per.yyyymm - INTERVAL 1 YEAR) and o.order_date < per.yyyymm + INTERVAL 1 MONTH) as `count`
from
(select DISTINCT LAST_DAY(order_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH as yyyymm
from orders) per
order by per.yyyymm

<强> Results

|                    yyyymm | count |
|---------------------------|-------|
| October, 01 2013 00:00:00 |     1 |
| January, 01 2014 00:00:00 |     5 |
|   March, 01 2014 00:00:00 |     6 |

查询2

select DATE_FORMAT(order_date, '%Y-%m'),
(select count(DISTINCT o.user_id) from orders o where o.order_date >= 
 (LAST_DAY(o1.order_date) + INTERVAL 1 DAY - INTERVAL 13 MONTH) and 
 o.order_date <= LAST_DAY(o1.order_date)) as `count`
from orders o1
group by DATE_FORMAT(order_date, '%Y-%m')

<强> Results

| DATE_FORMAT(order_date, '%Y-%m') | count |
|----------------------------------|-------|
|                          2013-10 |     1 |
|                          2014-01 |     5 |
|                          2014-03 |     6 |

答案 2 :(得分:1)

我能做的最好的事情是:

SELECT Date, COUNT(*) as ActiveUsers
FROM 
(
    SELECT DISTINCT userId, CONCAT(YEAR(order_date), "-", MONTH(order_date)) as Date
    FROM `a` 
    ORDER BY Date
)
AS `b`
GROUP BY Date

输出如下:

|    Date | ActiveUsers |
|---------|-------------|
| 2013-10 |           1 |
|  2014-1 |           4 |
|  2014-3 |           4 |

现在,您需要为每一行总结前一行中的活动用户数。 例如,这是C#中的代码。

int total = 0;
while (reader.Read())
{ 
    total += (int)reader['ActiveUsers'];
    Console.WriteLine("{0} - {1} active users", reader['Date'].ToString(), reader['ActiveUsers'].ToString());
}

顺便说一下,对于2014年3月,答案是9,因为一行是重复的。

答案 3 :(得分:1)

试试这个,但是这并没有处理最后一部分:2014年1月的价值 - 包括2013年10月

select TO_CHAR(order_dt,'MON-YYYY'), count(distinct User_ID ) cnt from [orders] 
where User_ID  in 
(select User_ID from
 (select a.User_ID from  [orders] a,
(select a.User_ID,count (a.order_dt) from [orders] a 
where a.order_dt > (select max(b.order_dt)-365 from [orders] b where a.User_ID=b.User_ID)
group by a.User_ID
having count(order_dt)>1) b
where a.User_ID=b.User_ID) a
)
group by TO_CHAR(order_dt,'MON-YYYY');

答案 4 :(得分:1)

这就是我认为您正在寻找的

SET @cnt = 0;
SELECT Period, @cnt := @cnt + total_active_users AS total_active_users
FROM (
  SELECT DATE_FORMAT(order_date, '%b-%Y') AS Period , COUNT( id) AS total_active_users
  FROM t
  GROUP BY DATE_FORMAT(order_date, '%b-%Y')
  ORDER BY order_date
) AS t

这是我得到的输出

Period      total_active_users
Oct-2013    1
Jan-2014    6
Mar-2014    10

您还可以执行COUNT(DISTINCT ID)以获取唯一的ID

这是SQL Fiddle