所以,我有一个带有用户ID(id
)和事务日期(dot
)的mysql表,如下所示:
id dot
-------------------------------
101 2015-06-12 12:18:42 UTC
102 2015-06-12 12:18:40 UTC
103 2015-06-12 12:18:42 UTC
101 2015-07-12 12:18:42 UTC
等等。 (此数据的输出应为:
Year Month Num of users
-----------------------------
2015 06 0
2015 07 2
)
它记录所有已完成的事务。对于每个月m
,我想了解按m-1
个月但未在m
个月内进行交易的月份和年份的用户数。结果需要按年和月分组。理想情况下,表格应该看起来像(http://sqlfiddle.com/#!9/b80f49/1)
Year Month Num of users
-----------------------------
2015 05 0
2015 06 2
2015 07 1
2015 08 4
现在一个月(例如2015年5月),我可以硬编码:
SELECT "2015" AS Year,"05" AS Month, "COUNT(DISTINCT id) FROM table WHERE
MONTH(dot)=4 AND YEAR(dot)=2015
AND id NOT IN
(SELECT id FROM table WHERE MONTH(dot)=5 AND YEAR(dot)=2015)
要使用GROUP BY
对用户数进行分组,查询将如下所示:
SELECT YEAR(dot) as Year,MONTH(dot),COUNT(DISTINCT id) as Month FROM table
WHERE id NOT IN(SELECT id FROM table
WHERE DATEDIFF(dot_parent,dot_this_table)<30 AND DATEDIFF(dot_parent,dot_this_table)>=0)
这里dot_parent是父查询的dot
,dot_this_table是子查询的dot
。现在问题是我无法在子查询中传递dot_parent。有没有办法以另一种方式执行此操作或构建查询,以使其逻辑结构保持相似,因为我必须对多个日期范围进行类似的查询。
答案 0 :(得分:1)
您必须对同一个表进行三次查询:一次显示月份,一次查找前几个月的用户,一次查询相关月份的用户匹配。您每月选择不同的用户,因为您对用户是否在一个月内有多个交易不感兴趣。
以下是完整的查询:
select
this_month.year,
this_month.month,
count(prev_month_users.user) - count(this_month_users.user) as users
from
(
select distinct year(timing) as year, month(timing) as month
from transactions
) this_month
left join
(
select distinct
year(timing) as year, month(timing) as month, id as user,
year(date_add(timing, interval 1 month)) as next_month_year,
month(date_add(timing, interval 1 month)) as next_month_month
from transactions
) prev_month_users
on prev_month_users.next_month_year = this_month.year
and prev_month_users.next_month_month = this_month.month
left join
(
select distinct year(timing) as year, month(timing) as month, id as user
from transactions
) this_month_users
on this_month_users.user = prev_month_users.user
and this_month_users.year = prev_month_users.next_month_year
and this_month_users.month = prev_month_users.next_month_month
group by this_month.year, this_month.month;
结果:
year month users 2015 5 0 2015 6 2 2015 7 1 2015 8 3
请注意,我显示八月份的三个用户(用户101,102,104)。用户101在7月份进行了两笔交易,但仍有三位用户在7月份进行了交易,但没有在8月进行交易。
这是你的SQL小提琴:http://sqlfiddle.com/#!9/b80f49/13