Best way to flatten out this table?
361137Jul 20 2011 — edited Jul 21 2011Lets 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