2 renwenhao123456 renwenhao123456 于 2018.01.09 10:48 提问

MySql实现类似于【按顺序分组】的功能

简化后的table大概是这样的

t_located
ID TIME AREAID
1  00:00  e048
2  00:01  e048
3  00:02  e048
4  00:03  e048
5  00:04  f032
6  00:05  f032
7  00:06  e048

业务场景:定位器每隔特定时间获取所在区域内的人员信息,如果获取到就添加到数据库,这样可以看出,有人在e048待了3分钟,之后去了f032待了2分钟,之后回到e048

如果人的位置没动,定位器会一直向数据库添加记录,但最终只要刚到该点的第一条记录

希望的查询结果:

ID TIME AREAID
1  00:00  e048
5  00:04  f032
7  00:06  e048

由于人可能从e048去到别处再回来,导致期望结果出现若干个e048所以没法按AREA ID进行分组

无语了,困扰很久这个问题,希望能够有大神帮助写出sql语句,前提是不修改原数据库的数据添加方式

如果sql语句真的无法满足需求,希望能够得到数据库层面的其他解决方案,我看到mysql有自定义函数什么的,但是我不懂,希望大神能够解决,谢谢!

8个回答

bleachguanyu
bleachguanyu   2018.01.09 11:22
已采纳

drop temporary table if exists tmp_located;
set @lag:='',@currs:='',@flag:=0;

create temporary table tmp_located
select ID,TIME,AREAID, @lag:=@currs as LAG_AREAID
, (@currs:=AREAID) as CUR_AREAID
, @flag:=if(@currs<>@lag,@flag:=1,0) as FLAG
from t_located
ORDER BY ID;

select ID, TIME, AREAID
from tmp_located
where FLAG=1

renwenhao123456
renwenhao123456 基本搞定了,谢谢大神,刚刚是因为数据库里还有个PERSON ID的筛选条件,没有在临时表里做导致的
4 个月之前 回复
renwenhao123456
renwenhao123456 结果就变成这个样了
4 个月之前 回复
renwenhao123456
renwenhao123456 LAG_NODEID=e059 CUR_NODEID=e069 FLAG=1
4 个月之前 回复
renwenhao123456
renwenhao123456 LAG_NODEID=e059 CUR_NODEID=e069 FLAG=1
4 个月之前 回复
renwenhao123456
renwenhao123456 LAG_NODEID=e059 CUR_NODEID=e069 FLAG=1
4 个月之前 回复
renwenhao123456
renwenhao123456 LAG_NODEID=e059 CUR_NODEID=e069 FLAG=1
4 个月之前 回复
renwenhao123456
renwenhao123456 LAG_NODEID=null CUR_NODEID=e069 FLAG=1
4 个月之前 回复
renwenhao123456
renwenhao123456 这是我修改过的代码,最后的select多写个FLAG=1 AND PERSONID='1304'
4 个月之前 回复
renwenhao123456
renwenhao123456 create temporary table tmp_located select ID_,NODEID,NODENAME,PERSONID,PERSONNAME, @lag:=@currs as LAG_NODEID , (@currs:=NODEID) as CUR_NODEID , @flag:=if(@currs<>@lag,@flag:=1,0) as FLAG from t_located ;
4 个月之前 回复
renwenhao123456
renwenhao123456 回复bleachguanyu: 大神,好像有点问题
4 个月之前 回复
renwenhao123456
renwenhao123456 回复bleachguanyu: 看上去可行,我在尝试着理解代码,改成真实数据库的语句
4 个月之前 回复
bleachguanyu
bleachguanyu 要点:偷偷看下上面一行的AREAID,看看是否一样,类似SQL Server的LAG
4 个月之前 回复
caozhy
caozhy   Ds   Rxr 2018.01.09 11:10

http://blog.csdn.net/yabingshi_tech/article/details/52179431
参考这个,不过它最后分组了下,取的是连续最多的,你不需要那个分组,就输出全部了。

caozhy
caozhy 回复renwenhao123456: 他复杂是因为他比你多一个步骤。你不要那么复杂的。
4 个月之前 回复
renwenhao123456
renwenhao123456 满足我的要求,但是太复杂了,我在尝试着理解一下,如果可以帮我稍微改一下的话我会很感激~
4 个月之前 回复
qq_39245311
qq_39245311   2018.01.09 11:41

你看看数据库事件能添加吗,插入数据时触发。不改数据库的话不好弄

u012970790
u012970790   2018.01.09 11:54

我有一个思路:
写一个存储过程,
1.先根据AREAID分组,
2.再根据AREAID查出每个分组的所有记录,遍历每个分组所有记录的ID,如果ID是连续的,取连续ID的最小值,放到临时表,如果ID不连续,直接放到临时表。
3.最后结果直接返回临时表记录
PS:可以在存储过程中直接建临时表(不会真实存在数据库中),存储过程执行完成就会自动删掉临时表。可以了解在存储过程中创建临时表语法。
总结:方法比较笨,但是逻辑上可行的,可尝试一下。

qq_36399629
qq_36399629   2018.01.09 17:59

额!过来看看,虽然知道没分了不过这样可以么
insert t_located(id,time,areaid) vlaues(……) where areaid != max(select AREAID from t_located order by time)

xsctangcheng
xsctangcheng   2018.01.09 11:14

想将sql进行按顺序排序:order by abs(字段名称) 然后按照相同的参数分组,就ok;

renwenhao123456
renwenhao123456 只要最后按AREA ID分组,结果就不可能出现重复的AREA ID,请稍微试验一下再回答谢谢,如果这么简单的话我也不会困扰很久了
4 个月之前 回复
qq_36481052
qq_36481052   2018.01.09 11:10

你 写一个触发器 离开A点,回到A点 只是修改时间 应该就行了

qq_39245311
qq_39245311   2018.01.09 11:06

我没有想到简单的sql方法。
不过可以新建一个表,用来存每次**新到地址的时间**,只要用当前输入地址和查到的最近一次地址比较,地址不一样的保存,很容易实现的。
保存的新表就是你需要的查询结果。

renwenhao123456
renwenhao123456 因为我不负责管数据存入的部分,所以这种方法要实现起来也是挺蛋疼的。我的想法是看看有没有我没想到的方法可以实现,如果可以的话我就不用改数据库了
4 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!