在子查询之间的 ORACLE 连接语句中选择顶部记录
Posted
技术标签:
【中文标题】在子查询之间的 ORACLE 连接语句中选择顶部记录【英文标题】:selecting top record in ORACLE join statement between subqueries 【发布时间】:2012-12-18 02:29:54 【问题描述】:我想请你帮忙构造一条 ORACLE SQL 语句:
使用工作表如下
Object | Operation | Time
A | Move | 12:01
B | Move | 12:02
C | Pickup | 12:03
D | Move | 12:04
B | Pickup | 12:05
得到如下结果表。
Object | Operation | Time | Cause
A | Move | 12:01 | C
B | Move | 12:02 | C
D | Move | 12:04 | B
这是为了找出哪个 Pickup 操作导致了每个 Move 操作。 “原因”列必须包含紧邻移动操作时间最短的取件作业记录的对象。
我有以下一些想法,但不知道怎么做。 -。它需要在 Move 的子查询和 Pickup 的子查询之间使用 join 语句 -。 Pickup 的子查询必须按要加入的移动记录进行分区 -。只能从 Pickup 子查询的每个分区中选择 top 记录
【问题讨论】:
不会minimum(colName)
解决您的第三个要求吗?祝你好运。
“时间”列的数据类型?
@shellter 必须为每条 Move 记录的 MIN()
@techdo 它在 DATE 虽然我只在示例中写了 HH:MM
【参考方案1】:
这是我的尝试:
select m.object, m.operation, m.time,
max(p.object) keep (dense_rank first order by p.time) cause,
max(p.time) keep (dense_rank first order by p.time) cause_time
from a m
join a p on (p.time > m.time)
where m.operation = 'Move'
and p.operation = 'Pickup'
group by m.object, m.operation, m.time;
见SQLFiddle
我已将列时间设为数字,这并不重要,因为它是可排序的。
我已将表格分成两部分,即 Moves 和 Pickups,并且按时进行连接,pickup
的时间大于 move
的时间。 (这种类型的连接在性能上不是很好)。然后我choose
最小的皮卡time
(first
子句,order by p.time
)。
【讨论】:
感谢您不仅提供SQL语句,还提供友好的解释:)【参考方案2】:这是我的尝试:
select object, operation, time, t.pobject
from a join
(select object pobject, time cur, lag(time,1, 0) over (order by time ) prev
from a
where operation = 'Pickup')t
on a.time > t.prev and a.time <= t.cur
where operation = 'Move';
Here is a sqlfiddle
【讨论】:
+1,但我仍然需要更多的研究来了解它是如何工作的 :) @ShonerSul,解释:内部选择只取'Pickup'行并使用lag
函数获取上一条记录的时间(所以基本上现在我有了所有的开始时间和结束时间'移动')。然后我可以将它与所有“移动”记录一起加入【参考方案3】:
有一个老派的
select j1.Object, j1.Operation, j1.Time, substr(min(j2.Time || j2.Object), 6) Cause
from job j1, job j2
where j1.Operation like 'Move'
and j1.Time < j2.Time
and j2.Operation like 'Pickup'
group by j1.Object, j1.Operation, j1.Time
这里是SQLFiddle
【讨论】:
喜欢这个,不使用花哨的“平台特定”功能。有人可以使用纯 SQL 吗? @cha 挺纯的 :) 把 substr() 换成 substring() 就可以得到 ANSI SQL 的解决方案了。 虽然我接受了另一个答案,因为它可以包含取件记录的其他列,但我个人更喜欢这个简单的答案:) @Shoner Sul 这个也可以包含任何列 ;) substr(min(j2.Time || j2.Operation), substr(min(j2.Time || j2.Time), substr( min(j2.Time || j2.Cause) :)以上是关于在子查询之间的 ORACLE 连接语句中选择顶部记录的主要内容,如果未能解决你的问题,请参考以下文章
选择带有“is null”子句的查询和子选择/左连接不返回结果