Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

selecting top record in ORACLE join statement between subqueries

Tags:

sql

oracle

I would like to ask for your help for constructing a single ORACLE SQL statement:

using job table as below

Object | Operation | Time  
A      | Move      | 12:01  
B      | Move      | 12:02  
C      | Pickup    | 12:03  
D      | Move      | 12:04  
B      | Pickup    | 12:05  

to get the result table as below.

Object | Operation | Time  | Cause  
A      | Move      | 12:01 | C  
B      | Move      | 12:02 | C  
D      | Move      | 12:04 | B 

This is to figure out which Pickup operation caused each Move operation.
"Cause" column must include Object of the pickup job record with smallest time right next to move operation.

I have some ideas as below but do not know how to.
-. It requires join statement between subquery for Move and subquery for Pickup
-. Subquery for Pickup must be partitioned by move record to be joined
-. Must select top record only from each partition of Pickup subquery

like image 823
Shoner Sul Avatar asked Dec 18 '12 02:12

Shoner Sul


People also ask

Which is faster join or subquery in Oracle?

The advantage of a join includes that it executes faster. The retrieval time of the query using joins almost always will be faster than that of a subquery. By using joins, you can minimize the calculation burden on the database i.e., instead of multiple queries using one join query.

Which is faster between join and subquery?

I won't leave you in suspense, between Joins and Subqueries, joins tend to execute faster. In fact, query retrieval time using joins will almost always outperform one that employs a subquery. The reason is that joins mitigate the processing burden on the database by replacing multiple queries with one join query.

How do you use subqueries in joins?

SQL Joins and Subqueries. An SQL Join statement is used to combine data or rows from two or more tables based on a common field between them. A subquery is a query that is nested inside a SELECT , INSERT , UPDATE , or DELETE statement, or inside another subquery.


3 Answers

This is my try:

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;

see SQLFiddle

I've put column time as number, this does not have any importance as it is sortable.

I've splitted the table in two, Moves and Pickups and the join is made on time, time of pickup being greater than time of move. (This type of join is not great on performance). Then I choose the pickup with smallest time(first clause, with order by p.time).

like image 61
Florin stands with Ukraine Avatar answered Sep 29 '22 09:09

Florin stands with Ukraine


This is my try:

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

like image 39
A.B.Cade Avatar answered Sep 29 '22 09:09

A.B.Cade


There is one from old-school

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

Here is SQLFiddle

like image 35
knagaev Avatar answered Sep 29 '22 07:09

knagaev