I am using the below query to get the results I have shown in the below table. I am looking to modify the query to get the expected result as shown in last table. I would like to align the latest timestamp (start_time) with the manufacture_date (string). Also, if a "manufacture_date" from Vehicles table doesn't have any result in modem_auth table then the lifecycle_mode, auth_status, start_time, end_time column should show NULL in the result. Basically I would like to show all the records from vehicles table.
SELECT v.vin,
date_Format(v.manufacture_date, 'yyyy-MM-dd') AS event_date,
"Vehicle Manufactured" AS event_desc,
m.lifecycle_mode,
m.auth_status,
m.start_time,
m.end_time
FROM vehicles v
INNER JOIN (SELECT vin, MAX(created_on) AS max_created_on FROM vehicles GROUP BY vin) v2
ON v.vin = v2.vin AND
v.created_on = v2.max_created_on
LEFT JOIN modem_auth m
ON v.vin = m.vin AND
(date_Format(v.manufacture_date, 'yyyy-MM-dd') BETWEEN TO_DATE(m.start_time) AND TO_DATE(m.end_time)) AND
save.vin_2 IN ('LMN12345', 'XYZ12345', 'ABC12345')
WHERE m.partition_region = 'NA' AND
m.partition_country = 'USA'
Result I am getting -
vin | event_date | event_desc | lifecycle_mode | auth_status | start_time | end_time |
---|---|---|---|---|---|---|
LMN12345 | 8/2/2021 | Vehicle Manufactured | NULL | WAITING_FOR_AUTH | 08/02/2021 16:35:15 | 09/02/2021 13:28:29 |
XYZ12345 | 11/12/2020 | Vehicle Manufactured | NORMAL | NOT_AUTHORIZED | 11/10/2020 05:09:44 | 11/12/2020 16:19:53 |
XYZ12345 | 11/12/2020 | Vehicle Manufactured | NORMAL | NOT_AUTHORIZED | 11/12/2020 16:19:53 | 06/12/2021 00:00:30 |
ABC12345 | 6/13/2019 | Vehicle Manufactured | NULL | UNPROVISIONED | 06/13/2019 21:20:42 | 06/13/2019 21:20:58 |
ABC12345 | 6/13/2019 | Vehicle Manufactured | NULL | WAITING_FOR_HOME_URL | 06/13/2019 21:20:58 | 06/13/2019 22:10:32 |
ABC12345 | 6/14/2019 | Vehicle Manufactured | NULL | WAITING_FOR_USER | 06/13/2019 22:10:32 | 11/01/2019 12:18:32 |
Expected Result -
vin | event_date | event_desc | lifecycle_mode | auth_status | start_time | end_time |
---|---|---|---|---|---|---|
LMN12345 | 8/2/2021 | Vehicle Manufactured | NULL | WAITING_FOR_AUTH | 08/02/2021 16:35:15 | 09/02/2021 13:28:29 |
XYZ12345 | 11/12/2020 | Vehicle Manufactured | NORMAL | NOT_AUTHORIZED | 11/12/2020 16:19:53 | 06/12/2021 00:00:30 |
ABC12345 | 6/14/2019 | Vehicle Manufactured | NULL | WAITING_FOR_USER | 06/13/2019 22:10:32 | 11/01/2019 12:18:32 |
CodePudding user response:
The issue is that you have multiple rows coming out of table m (modem_auth) for a single vin. You need to boil the rows coming out of m down to a maximum of one per vin, which means you will need to make a table expression out of it that includes a group by vin
clause. (I'm a little confused about the event_date column in the first table, as if vin is the primary key of vehicles you wouldn't have two different dates for the same vin as the table shows for ABC12345.)
What you need to do is create a table expression based on modem_auth that identifies the one row per vin that you want to use in the outer join to vehicles, that row being the one with the latest start_time. So replace
LEFT JOIN modem_auth m
ON v.vin = m.vin AND
(date_Format(v.manufacture_date, 'yyyy-MM-dd') BETWEEN TO_DATE(m.start_time) AND TO_DATE(m.end_time))
with
LEFT JOIN modem_auth m
INNER JOIN (select ma2.vin, max(ma2.start_time) AS start_time from modem_auth ma2
INNER JOIN vehicles v2 ON v2.vin = ma2.vin
AND date_Format(v2.manufacture_date, 'yyyy-MM-dd') BETWEEN
TO_DATE(ma2.start_time) AND TO_DATE(ma2.end_time)
group by ma2.vin) mamax ON m.vin = mamax.vin AND m.start_time = mamax.start_time
ON v.vin = m.vin AND
(date_Format(v.manufacture_date, 'yyyy-MM-dd') BETWEEN TO_DATE(m.start_time) AND TO_DATE(m.end_time))