我不知道这是否可以通过子查询有效实现,或者如何为此构建查询。我必须提取一些关于不再使用我们系统的人的知识。想象一下,我们有3个用户ID为1024,1234和5678的用户;用户1024和1234正在使用主题A,而5678正在使用主题B:
$ SELECT * FROM user; | $ SELECT * FROM user_theme;
+------+------+ | +------+-------+
| id | name | | | user | theme |
+------+------+ | +------+-------+
| 1024 | John | | | 1024 | A |
| 1234 | Jane | | | 1234 | A |
| 5678 | Jeff | | | 5678 | B |
+------+------+ | +------+-------+
使用情况跟踪表如下所示:
$ SELECT * FROM user_usage;
+----+------+---------------------+------+
| id | user | date | uses |
+----+------+---------------------+------+
| 1 | 1234 | 2014-08-02 00:00:00 | 5 |
| 2 | 1234 | 2014-08-03 00:00:00 | 5 |
| 3 | 1234 | 2014-08-04 00:00:00 | 3 |
| 4 | 1234 | 2014-08-05 00:00:00 | 6 |
| 5 | 1024 | 2014-08-02 00:00:00 | 8 |
| 6 | 1024 | 2014-08-03 00:00:00 | 7 |
| 7 | 1024 | 2014-08-04 00:00:00 | 4 |
| 8 | 1024 | 2014-08-05 00:00:00 | 6 |
| 9 | 1024 | 2014-09-02 00:00:00 | 1 |
| 10 | 1024 | 2014-09-03 00:00:00 | 2 |
| 11 | 1024 | 2014-09-04 00:00:00 | 3 |
| 12 | 1024 | 2014-09-05 00:00:00 | 4 |
| 13 | 5678 | 2014-08-02 00:00:00 | 8 |
| 14 | 5678 | 2014-08-03 00:00:00 | 7 |
| 15 | 5678 | 2014-08-04 00:00:00 | 4 |
| 16 | 5678 | 2014-08-05 00:00:00 | 6 |
| 17 | 5678 | 2014-09-02 00:00:00 | 1 |
| 18 | 5678 | 2014-09-03 00:00:00 | 2 |
| 19 | 5678 | 2014-09-04 00:00:00 | 3 |
| 20 | 5678 | 2014-09-05 00:00:00 | 4 |
+----+------+---------------------+------+
我想了解分析情况,看看2014-09中我们的系统使用量有多少(又名:2014 - 08年有使用数据,但不再是2014-09),按主题分组。所以我想写一些类似的东西:
SELECT
user_theme.theme,
SUM(user_usage.users) 'uses lost'
FROM
user_theme
LEFT JOIN user_usage
ON user_theme.user = user_usage.user
WHERE
...
GROUP BY
user_theme.theme
# HAVING ...?
得到如下结果:
+-------+-----------+
| theme | uses lost |
+-------+-----------+
| A | 19 |
| B | 0 |
+-------+-----------+
19来自SUM(uses)
WHERE user = 1234 AND YEAR(date) = 2014 AND MONTH(date) = 8
。
我事先并不知道我关心来自user = 1234的SUM(uses)
,因为我只知道我需要在SUM(uses)
的WHERE子句中包含用户1234,因为{{ 1}} SUM(uses)
为0。
实际上有很多用户,以及一些主题(大约20K用户,大约10个主题),所以理想情况下,我认为我想避免在代码中进行过滤直接在数据库中。有没有办法在MySQL中使用原始SQL查询有效地做到这一点?
答案 0 :(得分:1)
以下是将当前月份与前一个月进行比较的查询:
set @current_month = now();
set @previous_month = date_sub(@current_month, interval 1 month);
set @current_month = concat(year(@current_month), month(@current_month));
set @previous_month = concat(year(@previous_month), month(@previous_month));
select a.`theme`, sum(ifnull(b.uses_lost,0)) as uses_lost
from
`user_theme` as a
left outer join
(
select `user`, sum(uses) as uses_lost
from `user_usage`
where concat(year(`date`), month(`date`)) = @previous_month
and `user` not in (
select `user`
from `user_usage`
where concat(year(`date`), month(`date`)) = @current_month)
group by `user`
) as b
on (a.`user`=b.`user`)
group by a.`theme`;
主要想法是查找上个月使用过系统且当月没有行的所有用户