如何在子查询mysql中传递参数?

时间:2015-10-12 12:01:55

标签: mysql group-by

所以,我有一个带有用户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。有没有办法以另一种方式执行此操作或构建查询,以使其逻辑结构保持相似,因为我必须对多个日期范围进行类似的查询。

1 个答案:

答案 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