所以我想逐个月地将新用户与表中的返回用户进行比较。我有一个表,其中包含用户名和日期戳的每个操作。
我可以轻松拉出执行操作的用户,例如2011年1月。要查看每个用户是否是新用户,我需要针对之前的所有记录(2011年1月之前)运行用户名。
在我的摸索中,我想出了以下内容:
SELECT ini.username,
MIN(ini.datetime) AS firstAction,
COUNT(ini.datetime) AS numMonth,
(SELECT COUNT(*)
FROM tableActions tot
WHERE tot.username = ini.username
AND tot.datetime < '201101%'
AND tot.datetime > '201001%') AS numTotal
FROM tableActions ini
WHERE DATETIME >= '201101%'
AND DATETIME < '201102%'
GROUP BY ini.username
ORDER BY firstAction
它没有错误,但它也没有完成。似乎非常激烈。
答案 0 :(得分:5)
您可以重新编写查询(假设tableactions.datetime
是DATETIME
数据类型):
SELECT ini.username,
MIN(ini.datetime) AS firstAction,
COUNT(ini.datetime) AS numMonth,
x.numTotal
FROM tableActions ini
LEFT JOIN (SELECT tot.username,
COUNT(*) AS numTotal
FROM tableActions tot
WHERE tot.datetime > '2010-01-01'
AND tot.datetime < '2011-01-01'
GROUP BY tot.username) x ON x.username = ini.username
WHERE ini.datetime BETWEEN '2011-01-01' AND '2011-01-31'
GROUP BY ini.username
ORDER BY firstAction
尽管使用username
,username
的覆盖索引值得考虑,但可能至少会在datetime
上设置索引。
datetime
比较看起来很可疑 - LIKE
是唯一支持通配符的。
答案 1 :(得分:1)
我认为使用合适的where子句进行简单的表到自身连接就足够了(这个查询直接来自我的头脑,未经测试):
SELECT curr_activity.username, COUNT(prev_activity.username) AS did_something_in_the_past
FROM tableActions AS curr_activity
LEFT JOIN tableActions AS prev_activity ON curr_activity.username = prev_activity.username
WHERE curr_activity.datetime >= '2011-01-01' AND curr_activity.datetime < '2011-02-01'
AND prev_activity.datetime < '2011-01-01'
GROUP BY curr_activity.username
索引很重要。您必须为username
和datetime
列编制索引,datetime
列必须是datetime
或类似的数据类型。
答案 2 :(得分:0)
SELECT username,
MIN(datetime) AS firstAction,
MAX(datetime) AS numMonth,
COUNT(*) AS numTotal
GROUP BY ini.username
HAVING numTotal > 1
WHERE DATETIME between '201001%' AND '201102%'
ORDER BY username
* I think this collapsed version is what you need ?
答案 3 :(得分:0)
我认为你可以替换
SELECT COUNT(*)
FROM tableActions tot
WHERE tot.username = ini.username
AND tot.datetime < '201101%'
AND tot.datetime > '201001%'
带
SELECT 1
FROM tableActions tot
WHERE tot.username = ini.username
AND tot.datetime < '201101%'
AND tot.datetime > '201001%' LIMIT 1
,所以它不必遍历所有记录并计算它们。