我的查询给出重复的记录。我想要trip_checkpoint_event表中的所有记录以及其他表中的相应值。
trip_hdr 是我的主表 trip_dtl_assign 是我的详细信息表 TRIP_CHECKPOINT 表处理一些详细信息, trip_checkpoint_event 表是 trip_checkpoint 的相应详细信息表。
SELECT * FROM TRIP_HDR WHERE TRIP_HDR_ID LIKE '166'
SELECT * FROM TRIP_DTL_ASSIN WHERE TRIP_HDR_ID LIKE '166'
SELECT * FROM TRIP_CHECKPOINT WHERE TRIP_HDR_ID LIKE '166'
SELECT * FROM trip_checkpoint_event WHERE CHECKPOINT_ID IN ('279','280','282')
SELECT * FROM trip_checkpoint_event WHERE CHECKPOINT_ID IN (
SELECT CHECKPOINT_ID FROM TRIP_CHECKPOINT WHERE TRIP_HDR_ID LIKE '166' )
下面是我的查询,我无法弄清楚我在哪里做错了连接
SELECT CHECKPOINT_EVT_ID,
CKPT.TRIPCODE,
CKPT.PROVIDER,
CKPT.TRUCK BRV,
CKPT.MASTER_DEVICE ,
CASE
WHEN SENSORID IS NULL THEN ' '
ELSE SENSORID
END SENSOR,
CASE
WHEN trip_checkpoint_event.TIMESTAMP = '0' THEN ' '
ELSE TS_GMT(trip_checkpoint_event.TIMESTAMP)
END SENSOR_OPEN_TIME,
CASE
WHEN CKPT.TIMESTAMP = '0' THEN ' '
ELSE TS_GMT (CKPT.TIMESTAMP)
END DATE_OF_DELIVERY,
CASE
WHEN CKPT.VOLUME IS NULL THEN 0
ELSE CKPT.VOLUME
END VOLUME ,
CASE
WHEN CKPT.PLANNED_CP = '1' THEN 'PLANNED'
WHEN CKPT.PLANNED_CP = '0' THEN 'UNPLANNED'
ELSE 'Other'
END PLANNED_CP_name,
CKPT.GEOZONE_CODE Delivery_point,
CKPT.TNXID TNXID,
CKPT.ORDERNO ORDERNO,
CKPT.PROVIDER,
CKPT.OMC OMC,
CKPT.ENTRY_DATE ENTRY_DATE,
CKPT.ORIGINATION ORIGINATION,
CKPT.BD Begin_Journey_Date,
CKPT.ED End_Journey_Date,
CKPT.TRANSPORTATION_TYPE
FROM trip_checkpoint_event
LEFT JOIN (***Select Checkpoint_ID,
TRIP_HDR_ID,
HDR.ASGNID,
HDR.SUBDIVID,
HDR.TRIPCODE,
HDR.BEGINDATE BD,
HDR.ENDDATE ED,
HDR.MASTERID MASTERID,
HDR.SUBDEVICE SUBDEVICE,
HDR.MASTER_DEVICE MASTER_DEVICE,
HDR.SUB_DEVICE SUB_DEVICE,
GEOZONE_CODE,
VOLUME,
TIMESTAMP,
PLANNED_CP,
HDR.TIMEZONE ZONE,
HDR.truck_code TRUCK,
HDR.DEVICE_STATUS,
HDR.SUB_DEVICE_STATUS,
HDR.TNXID TNXID,
HDR.PROVIDER PROVIDER,
HDR.OMC OMC,
HDR.ORDERNO ORDERNO,
HDR.ORIGINATION ORIGINATION,
HDR.ENTRY_DATE ENTRY_DATE,
CASE
WHEN (HDR.trip_type = '1' AND HDR.prime_type = '2') THEN '1'
ELSE HDR.trip_type
END AS trip_type,
CASE
WHEN trip_type = '1' THEN 'Prime Mover'
WHEN trip_type = '2' THEN 'Fuel Truck'
WHEN trip_type = '3' THEN 'Transit Vehicle'
WHEN trip_type = '4' THEN 'BLC on Rail'
WHEN trip_type = '5' THEN 'Container on Rail'
WHEN trip_type = '6' THEN 'Close Truck'
ELSE 'Other'
END TRANSPORTATION_TYPE
from trip_checkpoint
LEFT JOIN (Select TH.TRIP_CODE TRIPCODE,
TD.TRIP_ASGN_ID ASGNID,
TD.DEVICE_ID,
TD.SUB_DEVICE_ID SUBDIVID,
TH.TRIP_HDR_ID as TRIP,
TD.BEGIN_JOURNEY_DATE BEGINDATE,
TD.OPEN_DATE ENDDATE,
TD.DEVICE_ID MASTERID,
TD.SUB_DEVICE_ID SUBDEVICE,
(SELECT DEVICE_code FROM DEVICE WHERE DEVICE.DEVICE_ID = TD.DEVICE_ID) AS MASTER_DEVICE,
(SELECT DEVICE_code FROM DEVICE WHERE DEVICE.DEVICE_ID = TD.SUB_DEVICE_ID) AS SUB_DEVICE,
(SELECT truck_code FROM truck trk WHERE trk.truck_id = TD.truck_id) truck_code,
(SELECT TIMEZONE FROM account_key acc_key WHERE acc_key.ID = TH.account_id) TIMEZONE,
(SELECT PROVIDER_NAME FROM ASC_PROVIDER PROV WHERE PROV.PROVIDER_ID = TH.PROVIDER_ID) PROVIDER,
(SELECT COMPANY_NAME FROM ASC_COMPANY CMP WHERE CMP.COMPANY_ID = TH.COMPANY_ID)
OMC,
th.regime_code TNXID,
th.agent_pin ORDERNO,
TH.TRIP_DATE ENTRY_DATE,
TH.ORIGINATION ORIGINATION,
TH.trip_type,
TH.prime_type,
TD.DEVICE_STATUS,
TD.SUB_DEVICE_STATUS
from TRIP_DTL_ASSIGN TD,
TRIP_HDR TH
WHERE TH.TRIP_HDR_ID = TD.TRIP_HDR_ID) HDR
ON HDR.TRIP = trip_checkpoint.TRIP_HDR_ID
WHERE HDR.TRIP = trip_checkpoint.TRIP_HDR_ID***) CKPT
ON trip_checkpoint_event.CHECKPOINT_ID = CKPT.Checkpoint_ID
WHERE PLANNED_CP != 9
这是测试数据
1.SELECT trip_hdr_id,trip_code FROM TRIP_HDR WHERE TRIP_HDR_ID LIKE '166'
166 TRN20191106-0002
2.SELECT TRIP_HDR_ID,TRIP_ASGN_ID FROM TRIP_DTL_ASSIGN WHERE TRIP_HDR_ID LIKE '166'
TRIP_HDR_ID TRIP_ASGN_ID
166 271
166 272
3.SELECT CHECKPOINT_ID,TRIP_HDR_ID FROM TRIP_CHECKPOINT WHERE TRIP_HDR_ID LIKE '166'
CHECKPOINT_ID TRIP_HDR_ID
279 166
280 166
281 166
282 166
4.SELECT CHECKPOINT_EVT_ID,CHECKPOINT_ID FROM trip_checkpoint_event WHERE CHECKPOINT_ID IN ('279','280','281','282')
CHECKPOINT_EVT_ID CHECKPOINT_ID
133 282
134 280
My expected result
CHECKPOINT_EVT_ID CHECKPOINT_ID
133 282
134 280
当我运行下面的完整查询时,结果是重复的。我知道这是join的问题。不知道如何纠正它。
CHECKPOINT_EVT_ID CHECKPOINT_ID
133 282
133 282
134 280
134 280
此部分正在生成重复项 *
Select Checkpoint_ID,
TRIP_HDR_ID,
HDR.ASGNID,
HDR.SUBDIVID,
HDR.TRIPCODE,
HDR.BEGINDATE BD,
HDR.ENDDATE ED,
HDR.MASTERID MASTERID,
HDR.SUBDEVICE SUBDEVICE,
HDR.MASTER_DEVICE MASTER_DEVICE,
HDR.SUB_DEVICE SUB_DEVICE,
GEOZONE_CODE,
VOLUME,
TIMESTAMP,
PLANNED_CP,
HDR.TIMEZONE ZONE,
HDR.truck_code TRUCK,
HDR.DEVICE_STATUS,
HDR.SUB_DEVICE_STATUS,
HDR.TNXID TNXID,
HDR.PROVIDER PROVIDER,
HDR.OMC OMC,
HDR.ORDERNO ORDERNO,
HDR.ORIGINATION ORIGINATION,
HDR.ENTRY_DATE ENTRY_DATE,
CASE
WHEN (HDR.trip_type = '1' AND HDR.prime_type = '2') THEN '1'
ELSE HDR.trip_type
END AS trip_type,
CASE
WHEN trip_type = '1' THEN 'Prime Mover'
WHEN trip_type = '2' THEN 'Fuel Truck'
WHEN trip_type = '3' THEN 'Transit Vehicle'
WHEN trip_type = '4' THEN 'BLC on Rail'
WHEN trip_type = '5' THEN 'Container on Rail'
WHEN trip_type = '6' THEN 'Close Truck'
ELSE 'Other'
END TRANSPORTATION_TYPE
from trip_checkpoint
LEFT JOIN (Select TH.TRIP_CODE TRIPCODE,
TD.TRIP_ASGN_ID ASGNID,
TD.DEVICE_ID,
TD.SUB_DEVICE_ID SUBDIVID,
TH.TRIP_HDR_ID as TRIP,
TD.BEGIN_JOURNEY_DATE BEGINDATE,
TD.OPEN_DATE ENDDATE,
TD.DEVICE_ID MASTERID,
TD.SUB_DEVICE_ID SUBDEVICE,
(SELECT DEVICE_code FROM DEVICE WHERE DEVICE.DEVICE_ID = TD.DEVICE_ID) AS MASTER_DEVICE,
(SELECT DEVICE_code FROM DEVICE WHERE DEVICE.DEVICE_ID = TD.SUB_DEVICE_ID) AS SUB_DEVICE,
(SELECT truck_code FROM truck trk WHERE trk.truck_id = TD.truck_id) truck_code,
(SELECT TIMEZONE FROM account_key acc_key WHERE acc_key.ID = TH.account_id) TIMEZONE,
(SELECT PROVIDER_NAME FROM ASC_PROVIDER PROV WHERE PROV.PROVIDER_ID = TH.PROVIDER_ID) PROVIDER,
(SELECT COMPANY_NAME FROM ASC_COMPANY CMP WHERE CMP.COMPANY_ID = TH.COMPANY_ID)
OMC,
th.regime_code TNXID,
th.agent_pin ORDERNO,
TH.TRIP_DATE ENTRY_DATE,
TH.ORIGINATION ORIGINATION,
TH.trip_type,
TH.prime_type,
TD.DEVICE_STATUS,
TD.SUB_DEVICE_STATUS
from TRIP_DTL_ASSIGN TD,
TRIP_HDR TH
WHERE TH.TRIP_HDR_ID = TD.TRIP_HDR_ID) HDR
ON HDR.TRIP = trip_checkpoint.TRIP_HDR_ID
WHERE HDR.TRIP = trip_checkpoint.TRIP_HDR_ID
*
答案 0 :(得分:0)
当您联接表GROUP BY
时发生行乘法。该表与下一部分之间没有1:1的关系。
这是您的示例数据:
trip_dtl_assign
这是您非常简化的查询:
with
trip_hdr(trip_hdr_id, trip_code) as (
select 166, 'TRN20191106-0002' from dual),
trip_dtl_assign(trip_hdr_id, trip_asgn_id) as (
select 166, 271 from dual union all
select 166, 272 from dual ),
trip_checkpoint(checkpoint_id, trip_hdr_id) as (
select 279, 166 from dual union all
select 280, 166 from dual union all
select 281, 166 from dual union all
select 282, 166 from dual ),
trip_checkpoint_event(checkpoint_evt_id, checkpoint_id) as (
select 133, 282 from dual union all
select 134, 280 from dual)
我尝试使用您的原始SQL,并将逻辑简化为上述形式。结果是:
select th.trip_hdr_id, trip_code, trip_asgn_id, checkpoint_evt_id, tcp.checkpoint_id
from trip_hdr th
join trip_dtl_assign tda on tda.trip_hdr_id = th.trip_hdr_id
join trip_checkpoint tcp on tcp.trip_hdr_id = th.trip_hdr_id
join trip_checkpoint_event tce on tce.checkpoint_id = tcp.checkpoint_id
那么,为什么Oracle会将ID 271分配给检查点280,将ID 272分配给检查点282(反之亦然)?这里的逻辑是什么?如果您回答此问题,则可以添加适当的加入条件。
您可以使用TRIP_HDR_ID TRIP_CODE TRIP_ASGN_ID CHECKPOINT_EVT_ID CHECKPOINT_ID
----------- ---------------- ------------ ----------------- -------------
166 TRN20191106-0002 271 134 280
166 TRN20191106-0002 272 134 280
166 TRN20191106-0002 271 133 282
166 TRN20191106-0002 272 133 282
两次为行编号:
row_number()
,然后仅选择r1 = r2的行,但我不知道这是否是您想要的。