我尝试使用局部变量来保存用户数的值,以便计算当前计数与之前的计数之间的比率。
我使用此查询:
SET @count = 0;
SELECT DATE_FORMAT(ual.time, "%M, %Y") as monthName,
@count as beforeCount,
count(DISTINCT ual.user_id)/@count as progress,
@count := count(DISTINCT ual.user_id) as afterCount
FROM user_activity_log ual
LEFT OUTER JOIN user u
ON u.gym = 22
LEFT OUTER JOIN (SELECT ualWeek.user_id FROM user_activity_log ualWeek
GROUP BY FROM_DAYS(TO_DAYS(ualWeek.time) -MOD(TO_DAYS(ualWeek.time) -1, 7)), ualWeek.user_id
HAVING count(ualWeek.user_id) > 1) weekUsers
ON u.id = weekUsers.user_id
LEFT OUTER JOIN (SELECT ualMonth.user_id FROM user_activity_log ualMonth
GROUP BY DATE(DATE_FORMAT(ualMonth.time, "%Y-%m-01")), ualMonth.user_id
HAVING count(ualMonth.user_id) > 5) monthUsers
ON u.id = monthUsers.user_id
WHERE
(ual.user_id = weekUsers.user_id OR ual.user_id = monthUsers.user_id) AND
((ual.time BETWEEN '2014-02-13' AND '2015-02-13') OR (('2014-02-13' IS NULL) OR ('2015-02-13' IS NULL)))
GROUP BY DATE(DATE_FORMAT(ual.time, "%Y-%m-01"))
我的问题是@count
没有更新自己。
这是我的结果:
如果我编辑我的查询并删除我的加入它的工作正常。 新查询:
SET @count = 0;
SELECT DATE_FORMAT(ual.time, "%M, %Y") as monthName,
@count as beforeCount,
count(DISTINCT ual.user_id)/@count as progress,
@count := count(DISTINCT ual.user_id) as afterCount
FROM user_activity_log ual
WHERE
((ual.time BETWEEN '2014-02-13' AND '2015-02-13') OR (('2014-02-13' IS NULL) OR ('2015-02-13' IS NULL)))
GROUP BY DATE(DATE_FORMAT(ual.time, "%Y-%m-01"))
@counter
答案 0 :(得分:0)
用户定义变量的行为无法保证使用SELECT语句,就像你使用它一样。
MySQL 5.5参考手册
的“9.4用户定义变量”部分的摘录对于其他语句,例如SELECT,您可能会得到您期望的结果,但这不能保证。在下面的语句中,您可能会认为MySQL将首先评估@a,然后再进行一次分配:
SELECT @a, @a:=@a+1, ...;
但是,涉及用户变量的表达式的评估顺序是未定义的。
参考:http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
您可以尝试(无保证)使用parens中的连接包装SELECT,并将其用作另一个查询的内联视图。至少通过5.5版本,该查询的结果将实现为派生表,外部查询将针对该查询运行。
方法是将结果集准备到派生表中,然后运行使用用户定义变量的外部查询,以“保留”前一行的值。再一次,没有保证,但这可能适合你:
SELECT DATE_FORMAT(d.dt, '%M, %Y') AS monthName
, d.cnt/@prev_count AS progress
, @prev_count := d.cnt AS cnt
FROM ( SELECT @prev_count := 0 ) i
JOIN ( SELECT DATE(DATE_FORMAT(ual.time, '%Y-%m-01')) AS dt
, COUNT(DISTINCT ual.user_id) AS cnt
FROM user_activity_log ual
LEFT
JOIN user u
ON u.gym = 22
LEFT
JOIN ( SELECT ualWeek.user_id
FROM user_activity_log ualWeek
GROUP
BY FROM_DAYS(TO_DAYS(ualWeek.time) -MOD(TO_DAYS(ualWeek.time) -1, 7))
, ualWeek.user_id
HAVING COUNT(ualWeek.user_id) > 1
) weekUsers
ON weekUsers.user_id = u.id
LEFT
JOIN ( SELECT ualMonth.user_id
FROM user_activity_log ualMonth
GROUP
BY DATE(DATE_FORMAT(ualMonth.time, '%Y-%m-01'))
, ualMonth.user_id
HAVING COUNT(ualMonth.user_id) > 5
) monthUsers
ON monthUsers.user_id = u.id
WHERE (ual.user_id = weekUsers.user_id OR ual.user_id = monthUsers.user_id)
AND ((ual.time BETWEEN '2014-02-13' AND '2015-02-13') OR (('2014-02-13' IS NULL) OR ('2015-02-13' IS NULL)))
GROUP BY DATE(DATE_FORMAT(ual.time, '%Y-%m-01'))
ORDER BY DATE(DATE_FORMAT(ual.time, '%Y-%m-01'))
) d