MySQL子查询计算
我有这个mysql查询,当我搜索一个用户时,他有一个登录名(开始-结束),它会在下一行显示总数。好的,但是如果用户有多个登录名(开始-结束),它不会在下一行显示总数MySQL子查询计算,mysql,vb.net,Mysql,Vb.net,我有这个mysql查询,当我搜索一个用户时,他有一个登录名(开始-结束),它会在下一行显示总数。好的,但是如果用户有多个登录名(开始-结束),它不会在下一行显示总数 SELECT CONCAT(u.lastname, ', ', u.firstname) AS Name , start.timestamp start , end.timestamp end , timediff(end.timestamp, start.timestamp) duration FROM use
SELECT CONCAT(u.lastname, ', ', u.firstname) AS Name
, start.timestamp start
, end.timestamp end
, timediff(end.timestamp, start.timestamp) duration
FROM user u
, user_group ug
, (
select *
, (
select event_id
from event L2
where L2.timestamp > L1.timestamp
and L2.user_bannerid = L1.user_bannerid
order by timestamp limit 1
) stop_id
From event L1
) start
join event end on end.event_id = start.stop_id
where start.status = 'In'
and end.status='Out'
and u.user_bannerid = start.user_bannerid
and ug.user_bannerid = u.user_bannerid
and ug.group_id = start.group_id
UNION
SELECT null, null, null, CAST(sum(duration) as Time)
FROM
(
SELECT CONCAT(u.lastname, ', ', u.firstname) AS Name
, start.timestamp start
, end.timestamp end
, timediff(end.timestamp, start.timestamp) duration
from user u
, user_group ug
, (
select *
, (
select event_id
from event L2
where L2.timestamp > L1.timestamp
and L2.user_bannerid = L1.user_bannerid
order by timestamp
limit 1
) stop_id
from event L1
) start
join event end on end.event_id = start.stop_id
where start.status = 'In'
and end.status = 'Out'
and u.user_bannerid = start.user_bannerid
and ug.user_bannerid = u.user_bannerid
and ug.group_id = start.group_id
) total
当用户只有一次登录时,它会显示总数
+----------------------------------------------------+---------------+
| Name | start | end | duration |
+----------------------------------------------------+---------------+
| User | 2011-11-24 02:12:05 | 2011-11-24 02:12:20 | 00:00:15 |
| | | | 00:00:15 |
+----------------------------------------------------+---------------+
但是当用户有多个登录时,它不会显示总小时数
+----------------------------------------------------+---------------+
| Name | start | end | duration |
+----------------------------------------------------+---------------+
| User | 2011-11-24 02:12:05 | 2011-11-24 02:12:20 | 00:00:15 |
| User | 2011-11-28 21:46:54 | 2011-11-28 21:53:01 | 00:06:17 |
| | | | |
+----------------------------------------------------+---------------+
我猜这与限制有关,但如果我将限制更改为大于1,我会得到“错误号1242子查询返回多行”。是否有人可以帮助我重新表述查询,以显示总小时数,无论他们有多少次登录
编辑:
仍然有这个问题,所以我提出了一个新的查询,但是我一直得到null而不是total。
知道为什么会这样吗
+----------------------------------------------------+---------------+
| Name | start | end | duration |
+----------------------------------------------------+---------------+
| User | 2011-11-24 02:12:05 | 2011-11-24 02:12:20 | 00:00:15 |
| User | 2011-11-28 21:46:54 | 2011-11-28 21:53:01 | 00:06:17 |
| User | 2011-11-28 21:46:54 | 2011-11-28 21:53:01 | null |
+----------------------------------------------------+---------------+
SELECT
CONCAT(u.lastname, ', ', u.firstname) AS Name,
start.timestamp AS start,
end.timestamp AS end,
TIME(SUM(TIMEDIFF(end.timestamp, start.timestamp))) AS duration
FROM user AS u
INNER JOIN user_group AS ug ON u.user_bannerid = ug.user_bannerid
INNER JOIN event AS start ON start.user_bannerid = u.user_bannerid AND start.status='In' AND start.group_id = ug.group_id
INNER JOIN event AS end ON end.user_bannerid = u.user_bannerid AND end.status='Out' AND start.event_id < end.event_id
GROUP BY start.event_id WITH ROLLUP
+----------------------------------------------------+---------------+
|名称|开始|结束|持续时间|
+----------------------------------------------------+---------------+
|用户| 2011-11-2402:12:05 | 2011-11-2402:12:20 | 00:00:15 |
|用户| 2011-11-2821:46:54 | 2011-11-2821:53:01 | 00:06:17|
|用户| 2011-11-2821:46:54 | 2011-11-2821:53:01 |空|
+----------------------------------------------------+---------------+
选择
CONCAT(u.lastname,,,u.firstname)作为名称,
start.timestamp作为开始,
end.timestamp作为结束,
时间(总和(TIMEDIFF(end.timestamp,start.timestamp))作为持续时间
从用户作为u
在u.user\u bannerid=ug.user\u bannerid上以ug的形式内部加入user\u组
内部加入事件,如start.user\u bannerid=u.user\u bannerid和start.status='In'和start.group\u id=ug.group\u id
内部加入事件作为end.user\u bannerid=u.user\u bannerid和end.status='Out'和start.event\u id
我认为最好的选择是在事件表中添加一个stop\u id,然后当用户注销时,使用out事件中的记录id更新In事件
对于现有记录,您可以根据问题中的逻辑编写查询以更新记录
完成此操作后,由于事件表中有一个stop_id,因此获取开始和停止时间是一个相对简单的查询
暂时不显示用户信息,您只需要以下内容即可获得详细信息:
SELECT start.timestamp start ,
end.timestamp end ,
timediff(end.timestamp, start.timestamp) duration
FROM event start join event end on end.event_id = start.stop_id
您不需要测试开始或停止状态,因为大概只有那些状态为
In
的事件才会有stop\u id
,而内部连接(假设这就是join在mysql中所做的)会阻止Out
记录被包含在顶层。其中00:00:32
来自第一个“OK”结果?对不起,输入错误。。。总共是00:00:15我们看到了结果。。。你能发布一些原始数据作为这个查询结果的基础吗。。。即使只是显示假用户名,但显示ID、状态、组和时间戳条目,这也会有更好的帮助。此外,一个人是否有可能在一行中有两个登录条目,但它们之间没有相应的注销。。。此外,如果用户在注销之前登录两次,查询将只进行第一次登录,并将其与注销进行匹配,然后减去差值以获得您的登录时间。希望这有帮助