我有以下MySQL查询:
SELECT concat('<a target="_new" href="%%WWWROOT%%/course/user.php?id=1&user=',
u.id,
'&mode=alllogs">',
u.firstname ,' ',
u.lastname,'</a>') AS Username,
count(*) AS logins ,
(SELECT count(*)
FROM mdl_log
WHERE userid = l.userid
GROUP BY userid) AS Activity
FROM mdl_log AS l
JOIN mdl_user AS u ON l.userid = u.id
WHERE action LIKE '%login%'
GROUP BY userid
ORDER BY Activity DESC
INTO OUTFILE '/tmp/Total_Logins_With_Total_Activity.txt';
我想扩展它,以便我可以根据数据范围得出结果,例如365天。
所以我想我可以改变上面的查询来从mdl_logs表中选择'time'字段并将其转换为days(它是一个unix时间戳),然后只选择当时间在最后365天内。任何帮助赞赏。
mdl_log 表格具有以下结构:
+--------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| time | int(10) unsigned | NO | MUL | 0 | |
| userid | int(10) unsigned | NO | MUL | 0 | |
| ip | varchar(15) | NO | | | |
| course | int(10) unsigned | NO | MUL | 0 | |
| module | varchar(20) | NO | | | |
| cmid | int(10) unsigned | NO | MUL | 0 | |
| action | varchar(40) | NO | MUL | | |
| url | varchar(100) | NO | | | |
| info | varchar(255) | NO | | | |
+--------+------------------+------+-----+---------+----------------+
mdl_user 表格如下:
+---------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| auth | varchar(20) | NO | MUL | manual | |
| confirmed | tinyint(1) | NO | MUL | 0 | |
| policyagreed | tinyint(1) | NO | | 0 | |
| deleted | tinyint(1) | NO | MUL | 0 | |
| mnethostid | bigint(10) | NO | MUL | 0 | |
| username | varchar(100) | NO | | | |
| password | varchar(32) | NO | | | |
| idnumber | varchar(255) | NO | MUL | | |
| firstname | varchar(100) | NO | MUL | | |
| lastname | varchar(100) | NO | MUL | | |
| email | varchar(100) | NO | MUL | | |
| emailstop | tinyint(1) unsigned | NO | | 0 | |
| icq | varchar(15) | NO | | | |
| skype | varchar(50) | NO | | | |
| yahoo | varchar(50) | NO | | | |
| aim | varchar(50) | NO | | | |
| msn | varchar(50) | NO | | | |
| phone1 | varchar(20) | NO | | | |
| phone2 | varchar(20) | NO | | | |
| institution | varchar(40) | NO | | | |
| department | varchar(30) | NO | | | |
| address | varchar(70) | NO | | | |
| city | varchar(20) | NO | MUL | | |
| country | varchar(2) | NO | MUL | | |
| lang | varchar(30) | NO | | en_utf8 | |
| theme | varchar(50) | NO | | | |
| timezone | varchar(100) | NO | | 99 | |
| firstaccess | int(10) unsigned | NO | | 0 | |
| lastaccess | int(10) unsigned | NO | MUL | 0 | |
| lastlogin | int(10) unsigned | NO | | 0 | |
| currentlogin | int(10) unsigned | NO | | 0 | |
| lastip | varchar(15) | NO | | | |
| secret | varchar(15) | NO | | | |
| picture | tinyint(1) | NO | | 0 | |
| url | varchar(255) | NO | | | |
| description | text | YES | | NULL | |
| mailformat | tinyint(1) unsigned | NO | | 1 | |
| maildigest | tinyint(1) unsigned | NO | | 0 | |
| maildisplay | tinyint(2) unsigned | NO | | 2 | |
| htmleditor | tinyint(1) unsigned | NO | | 1 | |
| ajax | tinyint(1) unsigned | NO | | 1 | |
| autosubscribe | tinyint(1) unsigned | NO | | 1 | |
| trackforums | tinyint(1) unsigned | NO | | 0 | |
| timemodified | int(10) unsigned | NO | | 0 | |
| trustbitmask | int(10) unsigned | NO | | 0 | |
| imagealt | varchar(255) | YES | | NULL | |
| screenreader | tinyint(1) | NO | | 0 | |
+---------------+---------------------+------+-----+---------+----------------+
答案 0 :(得分:1)
马克的回答很好并且给你最后365天,在间隔上添加上限是微不足道的,但是查询效率低于它可能的效果 - 从mdl_log读取两次:
SELECT concat('<a target="_new" href="%%WWWROOT%%/course/user.php?id=1&user=',
u.id,
'&mode=alllogs">',
u.firstname ,' ',
u.lastname,'</a>') AS Username,
SUM(IF(l.action LIKE '%login%', 1, 0)) AS logins,
COUNT(*) AS Activity
FROM mdl_log AS l
JOIN mdl_user AS u ON l.userid = u.id
WHERE l.time BETWEEN
UNIX_TIMESTAMP(ADDDATE(now(),INTERVAL -200 day)
AND UNIX_TIMESTAMP(ADDDATE(now(),INTERVAL -100 day)
GROUP BY userid
HAVING SUM(IF(l.action LIKE '%login%', 1, 0))>0
ORDER BY Activity DESC
INTO OUTFILE '/tmp/Total_Logins_With_Total_Activity.txt';
答案 1 :(得分:0)
如果将未转换的表列与其自身类型的值进行比较,查询可能会表现得更好 - 如下所示:
SELECT concat('<a target="_new" href="%%WWWROOT%%/course/user.php?id=1&user=',
u.id,
'&mode=alllogs">',
u.firstname ,' ',
u.lastname,'</a>') AS Username,
count(*) AS logins ,
(SELECT count(*)
FROM mdl_log
WHERE userid = l.userid
GROUP BY userid) AS Activity
FROM mdl_log AS l
JOIN mdl_user AS u ON l.userid = u.id
WHERE l.action LIKE '%login%' AND
l.time >= unix_timestamp(adddate(date(now()),interval -365 day)
GROUP BY userid
ORDER BY Activity DESC
INTO OUTFILE '/tmp/Total_Logins_With_Total_Activity.txt';
如果您想考虑闰年,可以使用interval -1 year
。