百分寻求一SQL语句的写法

查询对象是中国移动通信提供的根据车辆的随车手机获得的一张车辆全国定位表

1.表中有如下列:
定位编号 车辆编号 车辆所在地区编号 定位时间 定位有效标志

2.各列的具体描述:
定位编号:本条定位信息的标识序号(主键)
车辆编号:可理解为车辆的车牌号(唯一)
车辆所在地区编号:据车辆随车手机获得的此车此刻(定位时间)所在的地区编号
定位时间:本次获得车辆定位的具体时间
定位有效标志:最近一次对所有车辆的定位信息的此标志位为1,其他为0

3.表相关信息:
a.移动通信方面每隔半小时向表中插入一次车辆定位的最新信息(每天48此插入)
b.此表系单独的一个表,无任何其他关联

4.查寻要求:
查出表中车辆抛锚(车辆位置连续在某地区)时间在某值以上的记录

---------------------------------------------------------------

declare @clbh int
declare aa cursor for
select 车辆编号 from 车辆全国定位表
open aa
fetch next from aa into @clbh
while @@fetch_status=0
begin
declare rq datatime,rq1 datetime
declare bb cursor for
select 定位时间 from 车辆全国定位表 where 车辆编号 =@clbh
open bb
fetch next from bb into @rq
fetc next from bb into @rq1
while @@fetch_status=0
begin
if datediff(hh,@rq,@rq1)>2 --连续时间
select * from 车辆全国定位表
where 定位时间 =@rq1
fetch next from bb into @rq
fetch next from bb into @rq1
end
close bb
deallocate bb
fetch next from aa into @clbh
end
close aa
deallocate aa
不一定对
只是提供一个思路

---------------------------------------------------------------

想想这个问题还是比较有趣的。试着写了一句sql语句
设表中字段为id,code,area,time,sign分别对应
定位编号、车辆编号、车辆所在地区编号、定位时间、定位有效标志

select a.code,a.area from t1 as a join
(select code,max(time) as Maxtime from t1 b
where code in (select code from t1 where sign=1)
and area<>(select area from t1 where code=b.code and sign=1)
group by code) as c on a.code=c.code
where a.time > c.Maxtime
group by a.code,a.area
having count(a.id)>= 4

实际应用中,可以分步来写,容易理解一些,我的思路是
1.得到一个临时列表,保存不在最近扫描的记录地点的最大时间
select code,max(time) as Maxtime into #temp from t1 a
where code in (select code from t1 where sign=1)
and area<>(select area from t1 where code=a.code and sign=1)
group by code
2.扫描这个表中从此时间到最大时间之间有记录数大于4条的记录
select a.code,a.area from t1 as a join #temp as b on a.code=b.code
where a.time > b.Maxtime
group by a.code,a.area
having count(a.id)>=4 and max(a.sign)=1

不过试着用一句sql语句解决问题是比较有趣的。
在上面的一句话中,关于子查询的部分感觉还有一些问题,只是也不知道如何优化才好,希望大家来讨论讨论。
---------------------------------------------------------------

近段时间,厌倦长代码。看到就头痛。不想动脑筋。
---------------------------------------------------------------

设表中字段为id,code,area,time,sign分别对应
定位编号、车辆编号、车辆所在地区编号、定位时间、定位有效标志
select * from table
where time>=m_time
and sign='1'
and code in
(
select code
from table group by code
having (count(distinct area)=1)
)

m_time是当前时间与车辆抛锚时间之差值。

---------------------------------------------------------------

呵,如果一辆车在开始(2 小时内)第一次在A地,第二第三次信息丢失,第四次在A地,能否认为车已在A地“抛锚”
---------------------------------------------------------------

问题的关键是对“抛锚”定义,按照你的说法,是:“在某地区停留时间在两小时以上(同一车辆连续在同一地区出现四次以上)”。
也就是说,对于上述各位的表结构来说,就是:
Code,Area相同的记录,Time连续出现的次数超过4次。
使用Sign的意义在于可以限制查询结果:只查询当前抛锚的车辆,过去曾经抛锚的不关心。-- 实际上,不使用Sign也行。
那么,思路就出来了:
1、对原表按Code排序,获得每组Code中每条记录按照时间顺序的编号(反序)。排除掉最大编号小于4的(从1开始)。放入临时表#temp中。
2、求出每辆车当前的位置area。(#temp中)
3、在#temp中查找存在area与当前area不同的code,排除之。
4、剩下的就是你需要的。

---------------------------------------------------------------

实现:
1、排序
select ,
(select count(
)+1
from t1 b
where b.code=a.code
and b.time>a.time
) as No
into #temp1
from t1 a

2、排除最大编号小于4的(从1开始):
select code,max(No) as MaxNo
into #temp2
from #temp1
group by code

select *
into #temp3
from #temp1
where code in(select code from #temp2 where MaxNo>3)

3、求出每辆车当前的位置area。(#temp中)
select code,area
into #temp4
from #temp3
where sign=1

4、在#temp中查找存在area与当前area不同的code,排除之:
select *
from #temp3
where code not in(select code
from #temp3
where area area not in(select area from #temp4)
)

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus