自联接表以提供没有空的记录

时间:2017-01-05 16:11:53

标签: sql oracle

我正在尝试不同的方法来实现以下输出。

CON_ID    Compartment    AMOUNT       EXP_DT
train     Compartment 1     100     '20-jan-2016' 

请查找下面使用的数据。

with src_t as 
(
select 'A' as miot_id,'Train' as Obj_id from dual
union
select 'B' as miot_id,'Candy' as obj_id from dual
),
eat as (
select 'Candy' as eat_id,'Compartment1' as compartment,'20-jan-2016' as exp_dt from dual
union
select 'Cookies' as eat_id,'Compartment2' as compartment,'20-feb-2016' as exp_dt from dual
),
miot_t as (
select 'A' as miot_id,'Compartment1' as vin from dual
UNION
select 'B' as miot_id,'Compartment2' as vin from dual
),
condition_t as (
select 'Train' as con_id,100 as amount from  dual
)

我尝试了以下查询。

Select  con_id,Compartment,amount
      , exp_dt
From    src_t
Left Join condition_t
        On condition_t.con_id = src_t.obj_id
Left Join eat
        On eat.eat_id = src_t.obj_id
Left Join miot_t
        On miot_t.miot_id = src_t.miot_id;

但它显示空值为。

CON_ID    Compartment    AMOUNT       EXP_DT
  null    Compartment 1     null     '20-jan-2016' 
 Train      null            100         null

我尝试过使用Max功能。这是一种方法。但是还有其他任何方式..像自我加入等。所以它不会影响性能。谢谢你的回答

这意味着火车上的车厢1有100万卢比的糖果,在2016年2月20日到期'

1 个答案:

答案 0 :(得分:0)

我有一种感觉,我正在为他们做某人的功课,但现在就是这样。左连接意味着始终包括左侧表中的表值(首先提到),即使右侧表中没有匹配值也是如此。 NULL将替换缺少的右表值。

在你的情况下,你只对匹配值感兴趣,你对非匹配值没兴趣,所以你想做一个内连接,而不是外连接('左连接'是'左外连'的简写加入')。一个好的做法是始终从容器表向内工作到包含的表。这使您的SQL更容易理解。这是我得到你想要的结果集的SQL:

WITH src_t
     AS (SELECT 'A' AS miot_id, 'Train' AS obj_id
           FROM DUAL
         UNION
         SELECT 'B' AS miot_id, 'Candy' AS obj_id
           FROM DUAL)
   , eat
     AS (SELECT 'Candy' AS eat_id, 'Compartment1' AS compartment, '20-jan-2016' AS exp_dt
           FROM DUAL
         UNION
         SELECT 'Cookies' AS eat_id, 'Compartment2' AS compartment, '20-feb-2016' AS exp_dt
           FROM DUAL)
   , miot_t
     AS (SELECT 'A' AS miot_id, 'Compartment1' AS vin
           FROM DUAL
         UNION
         SELECT 'B' AS miot_id, 'Compartment2' AS vin
           FROM DUAL)
   , condition_t
     AS (SELECT 'Train' AS con_id, 100 AS amount
           FROM DUAL)
SELECT con_id
     , compartment
     , amount
     , exp_dt
  FROM condition_t
       INNER JOIN src_t ON con_id = obj_id
       INNER JOIN miot_t ON src_t.miot_id = miot_t.miot_id
       INNER JOIN eat ON eat.compartment = miot_t.vin;