我有表entrances
,用于记录用户进入房间并走出房间的时间。这样的事情:
user | action | time
-------------------------------------------
Ivan | in | 2016-08-28 12:00:00
John | in | 2016-08-28 12:00:01
Ann | in | 2016-08-28 12:00:02
Ivan | out | 2016-08-28 12:00:03
Ivan | in | 2016-08-28 12:00:04
Ann | out | 2016-08-28 12:00:05
Ivan | out | 2016-08-28 12:00:06
Mike | in | 2016-08-28 12:00:07
John | out | 2016-08-28 12:00:08
Ann | out | 2016-08-18 12:00:09
John | in | 2016-08-18 12:00:10
John | out | 2016-08-18 12:00:11
Ann | in | 2016-08-18 12:00:12
用户操作是独立的。只知道第一个操作总是in
,用户无法in
两次out
(并反转)。
我的目标是找到目前在场的所有用户。
我有两个想法:
out
in
的用户
in
的计数为out
如何在mysql上实现这个?还是其他任何想法?
用于测试的SQL:
CREATE TABLE `entrances` (
`id` int(11) NOT NULL,
`user` varchar(10) COLLATE utf8_bin NOT NULL,
`action` varchar(3) COLLATE utf8_bin NOT NULL,
`time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `entrances` (`id`, `user`, `action`, `time`) VALUES
(1, 'Ivan', 'in', '2016-08-28 12:00:00'),
(2, 'John', 'in', '2016-08-28 12:00:01'),
(3, 'Ann', 'in', '2016-08-28 12:00:02'),
(4, 'Ivan', 'out', '2016-08-28 12:00:03'),
(5, 'Ivan', 'in', '2016-08-28 12:00:04'),
(6, 'Ann', 'out', '2016-08-28 12:00:05'),
(7, 'Ivan', 'out', '2016-08-28 12:00:06'),
(8, 'Mike', 'in', '2016-08-28 12:00:07'),
(9, 'John', 'out', '2016-08-28 12:00:08'),
(10, 'Ann', 'out', '2016-08-28 12:00:09'),
(11, 'John', 'in', '2016-08-28 12:00:10'),
(12, 'John', 'out', '2016-08-28 12:00:11'),
(13, 'Ann', 'in', '2016-08-28 12:00:12');
ALTER TABLE `entrances` ADD PRIMARY KEY (`id`);
答案 0 :(得分:5)
time
获取最后一个操作user
user
action = in
带where
子句喜欢这个
select e.*
from entrances e
join
(
select user, max(time) as mtime
from entrances
group by user
) t on t.user = e.user
and t.mtime = e.time
where e.action = 'in'
答案 1 :(得分:1)
使用操作<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
加入所有行,并选择没有out
操作或out
操作更新
in
答案 2 :(得分:0)
我会尝试这样的事情,但是测试真实数据会更好。
select user from entrances e inner join
(select user, count(*) cnt from entrances where action='in') as e_in
on e.user=e_in.user left join
(select user, count(*) cnt from entrances where action='out') as e_out
on e.user=e_out.user
where e_out.user is null or (e_in.cnt - e_out.cnt) = 1
答案 3 :(得分:0)
我的想法1的Mysql实现:
SELECT e.* FROM entrances e
WHERE NOT EXISTS (
SELECT * FROM entrances WHERE e.user=user AND action="out" AND time > (
SELECT MAX(time) FROM entrances WHERE e.user=user AND action="in"
)
)
这按照字面意思书写:找到在out
之后没有in
的用户。利用NOT EXISTS功能。优点是可读性,没有魔法,简单的algorythm。