举个例子
表A
id timeA
0 2014-01-01 00:00:00
1 2014-01-02 00:00:00
2 2014-01-03 00:00:00
表B
Aid timeB
0 2014-01-01 00:00:02
0 2014-01-01 00:00:11
0 2014-01-01 00:00:10
1 2014-01-02 00:00:02
1 2014-01-02 00:00:03
1 2014-01-02 00:00:04
2 2014-01-03 00:00:02
2 2014-01-03 00:00:03
2 2014-01-03 00:00:04
sql:
select * from A
left join B
on (min(abs(timeA - timeB)))
结果:
id timeA Aid timeB
0 2014-01-01 00:00:00 0 2014-01-01 00:00:02
1 2014-01-02 00:00:00 1 2014-01-02 00:00:02
2 2014-01-03 00:00:00 2 2014-01-03 00:00:02
意思大概是这个意思,但是具体要怎么写呢?
(min(abs(timeA - timeB)))这里要怎么写?
我试一下这个问题会不会重新排到问题列表的首页,大家可以不用回答的
Mission Impossible.
Are you sure
@刘宏玺:
Definitely!
@爱编程的大叔: 我的豆就这么白费了?
@刘宏玺:
能拿去做成豆腐吗?我在发愁这么豆有啥用,要不问下DUDU是不是可以申请换成美刀。
一个豆豆一美刀。
@爱编程的大叔: 我再等等!其实我是有答案的
@刘宏玺:
如果你能缩小条件。
比如Table A一定是整点的,有个方法是先对Table B进行处理,
类似Convert(Time) to 整点, Time-整点 as differTime
然后再取DifferTime最小的出来,再join,
不过这么麻烦,我估计性能也不会好了,不清楚什么样的环境需要用到这样的处理。
我个人的偏好还是在设计环节尽量做好,否则后期就会有这种问题。
还有一种选择就是如果这个处理是耗时的,就将操作看看能不用用静态表的方式保存起来。
@爱编程的大叔: 我确实是用整点来实现的,不过这样不准!表B中有几百万的数据,效率太低了
@爱编程的大叔: 1分14秒才出结果
@刘宏玺:
我不清楚你是否可以动到Table B的设计,一种就是将Table b字段拆成两个。
另一种就是将查询出来的结果(可以用程序代码,也可以用SQL)进行缓存,直接保存为静态表。
@刘宏玺:
我知道一定很慢的,你只问SQL,我就只能答SQL。
但我比较擅长的还是综合性的解决方案。
@爱编程的大叔: 其实有一个很笨的做法,我不知道这种现实不现实,但我知道可以实现,大叔给分析下!
select * from A
left join B
on timeA = timeB or abs(timeA - timeB) = 1秒 or abs(timeA - timeB) = 2秒 or 。。。。。 or abs(timeA - timeB) = 1小时
@刘宏玺: 有一种结构是可以让人一看就知道怎么折腾都没有用的。你这个数据库设计或者需求恰好就是属于这种,你要是还想问的话,把原始需求拿出来,别在这上面折腾了。
@爱编程的大叔: 需求很简单,就是导出来的数据做个图表,看一下趋势,只用一次的,不用考虑效率之类的,表A和表B不需要在一个系统中使用,他们是两个数据库中的数据,一个是传感器监测的数据,一个是人工监测的数据,目的是看一下传感器监测的数据是否准确
@刘宏玺:
这种情况我会考虑用代码,而非数据库查询实现。
因为不需要整段数据全部出来,用代码方式,实际上是可以一个数据一个数据处理,动态显示的。
前台的反馈是很快的,甚至可以这么说,直接做个监视UI。
@爱编程的大叔: 倒也不用这个复杂,一个excel就可以搞定的
加条件啊
这还用你说,我就是问的条件怎么加
其实换个角度思考一下就好了
select id, min(diffTime) as minTime
from(
select A.id, abs(A.timeA-B.timeB) as diffTime
from A left join B on A.id=B.id
) T
group by id
你这种确实可以把最小时间求出来,感谢回答!
@刘宏玺: 效果理想吗
@Albert Fei: 没有试过啊,理论上可行,不过我已经是实现了
@刘宏玺: 我是想问你我写的SQL语句在你的实际程序中跑得快不快,运行效率怎么样?
如果数据很大的话,可能还要优化一下.
我自己写的语句我当然知道能运行出你要的结果,如果不能运行出你要的结果,我就不写出来了.
还有问题解决了,也应该结贴了~~~~~~~~
@Albert Fei: 其实你写的这个有个问题的,我需要的是当做连接条件,但是min(diffTime)有两个值,一个是正的,一个是负的,这就有点麻烦了,我就没试过
@刘宏玺: 时间差最小可以当作筛选条件,不好当作连接条件。
“但是min(diffTime)有两个值,一个是正的..."
这个怎么会有二个值,我也没有试过。按理论来讲abs(A.timeA-B.timeB)是取了绝对值的,怎么还会有负的值?
@Albert Fei: 当你用来做连接条件的时候,只是用了正值,也就是A.timeA>B.timeB
A.timeA<B.timeB的值是负的,体现不出来
@刘宏玺: 你为什么非要写到连接条件里,那样写是简洁还是效率高?
如果你非要写在连接条件里,你也可以用负值得的。你是怎么写体现不出来的?
再说你是想找出最小的,不管正值最小,还是负值最小,只要是最小找出来就行了;你也不是说要把正值最小找出来,再找负值最小找出来。
如果你有比我写的简洁,请贴出来让我学下你是怎么写的。
@Albert Fei: 哦,我明白了,你是没有理解我的这个问题,找出的最小值是用来做两个表的连接条件的
不是你想象的这么简单的
我给你说一下这个实际的问题:
在数据库中有一个专门存输电线路上面传感器的监控信息,有很多线路都有这种传感器,里面有一个参数是导线浮冰厚度,这个基本上十多分钟就会插入一条新的数据,
为了验证这些传感器传的值是否正确,进行了一次人工观察浮冰厚度,人工观察的可以认为是每个传感器只记录一次数据,
现在需要进行传感器监测的数据与人工观察的数据的对比,也就是说要找到传感器监测的数据时间与人工观察的时间最接近的那个传感器监测的数据,注意,需要的是最近时间的数据,不是最近时间
@刘宏玺: 你的意思也就是有二个表,A表是机器的数据,里面有很多条,数据量大一些;B表是人工观测的数据,数据量小一些.
现在是取min(abs(A.Time-B.Time)) 不就是取到了机器与人工观测的时间上最接近的那些数据了吗
@Albert Fei: 你取的只是最接近的时间好不好
@刘宏玺: 你要的不就是最接近的数据吗
我看你给出的示例就是最接近的数据,如下:
id timeA Aid timeB
0 2014-01-01 00:00:00 0 2014-01-01 00:00:02
1 2014-01-02 00:00:00 1 2014-01-02 00:00:02
2 2014-01-03 00:00:00 2 2014-01-03 00:00:02
@Albert Fei: 知道id了,自然知道数据了
@刘宏玺: 都不知道你到底想干什么?
当然要知道二个表里有对应的ID, 只不过对应的ID在A,B二个表中数据条数不一样。
按照日期(年月日)分组,然后计算差值,通过差值正序排,取每个组的第一个。