Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Best way to flatten out this table?

361137Jul 20 2011 — edited Jul 21 2011
Lets say you're dealing with these two tables:

CREATE TABLE VEHICLES
(
VEHICLE_ID NUMBER,
VEHICLE_NAME VARCHAR2(100 BYTE),
MILES NUMBER
);


CREATE TABLE VEHICLE_PARTS
(
PART_ID NUMBER,
VEHICLE_ID NUMBER NOT NULL,
PART_TYPE NUMBER NOT NULL,
PART_DESCRIPTION VARCHAR2(1000 BYTE) NOT NULL,
START_SERVICE_DATE DATE NOT NULL,
END_SERVICE_DATE DATE,
PART_TYPE_NAME VARCHAR2(100 BYTE)
);

And some example data as follows:

Insert into VEHICLES (VEHICLE_ID, VEHICLE_NAME, MILES) Values (1, 'Honda Civic', 75500);
Insert into VEHICLES (VEHICLE_ID, VEHICLE_NAME, MILES) Values (2, 'Ford Taurus', 156000);

Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, END_SERVICE_DATE, PART_TYPE_NAME)
Values
(1, 1, 1, '1.4 VTEC',
TO_DATE('07/07/2009 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('05/03/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'ENGINE');
Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, PART_TYPE_NAME)
Values
(2, 1, 1, '1.6 VTEC',
TO_DATE('05/03/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'ENGINE');
Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, END_SERVICE_DATE, PART_TYPE_NAME)
Values
(3, 1, 2, 'Good Year All-Season',
TO_DATE('07/07/2009 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('08/10/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'TIRES');
Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, PART_TYPE_NAME)
Values
(4, 1, 2, 'Bridgestone Blizzaks',
TO_DATE('08/10/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'TIRES');
Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, PART_TYPE_NAME)
Values
(5, 2, 1, '3.5 L Duratec',
TO_DATE('06/01/2008 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'ENGINE');
Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, END_SERVICE_DATE, PART_TYPE_NAME)
Values
(6, 2, 2, 'Good Year All-Season',
TO_DATE('06/01/2008 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('03/15/2009 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'TIRES');
Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, END_SERVICE_DATE, PART_TYPE_NAME)
Values
(7, 2, 2, 'Michelin All-Seaon',
TO_DATE('03/15/2009 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('01/12/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'TIRES');
Insert into VEHICLE_PARTS
(PART_ID, VEHICLE_ID, PART_TYPE, PART_DESCRIPTION, START_SERVICE_DATE, PART_TYPE_NAME)
Values
(8, 2, 2, 'Nokian',
TO_DATE('01/12/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'TIRES');


And you need to produce a view which displays the joined data flattened out where each vehicle has one row with columns representing their most current part (by what has a service start date with null end date).

Like this:

Vehicle: Engine: Tires:
Honda Civic 1.6 VTEC Bridgestone Blizzaks
Ford Taurus 3.5 L Duratec Nokian


Is there a fast/efficient way to do this?

My current approach which is the brute force method is to have a separate outer join for each column I need to pull with condition of max(START_SERVICE_DATE) to get the current part for each type (Engine, Tires, etc...).

but its so slow and painful code.

i thought about Pivot but I dont think Pivot would help here since there is no aggregation going on, right?

Could anything with partition over help? Im not familiar with that syntax
This post has been answered by Frank Kulash on Jul 21 2011
Jump to Answer
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 18 2011
Added on Jul 20 2011
6 comments
1,435 views