oracle join创建重复记录

时间:2019-11-17 16:49:41

标签: sql oracle join

我的查询给出重复的记录。我想要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

*

1 个答案:

答案 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的行,但我不知道这是否是您想要的。