【问题标题】:Left Join returns duplicate (two) rows with different attribute values (one column contains joined value, other contains null)左连接返回具有不同属性值的重复(两)行(一列包含连接值,另一列包含空值)
【发布时间】:2016-10-20 06:20:42
【问题描述】:

我有两张桌子:

人员表:

 ---------------------
|Person_ID | Phone_ID |
|---------------------|
|1234      | 12       |
|345       | 10       |
|43        | 33       |
|55        | 27       |
-----------------------

电话桌:

 --------------------------
|Phone_ID  |  Phone_Number |
|--------------------------|
|  12      |  null         |
|  10      |  9876         |
|  33      |  9654         |
|  27      |  null         |
 --------------------------

当我执行查询时:

select t1.person_id, t2.phone_id 
from person t1
left join
phone t2
on t1.phone_id=t2.phone_id;

我得到结果:

 --------------------------
| Person_ID | Phone_number |
|--------------------------|
| 1234      | null         |
| 345       | 9876         |
| 345       | null         |
| 43        | 9654         |
| 43        | null         |
| 55        | null         |
 --------------------------

如何消除为已经有电话号码的人员 ID 获取 null 值的问题?

【问题讨论】:

  • 用你的数据&选择是不可能得到这个结果的。
  • 正如 dnoeth 所说,您的选择无法从指定的表数据中返回该结果。
  • 根据您的示例数据,结果应仅包含 4 行。但是,在您的输出中,ID 345 和 43 有两行。
  • 您的查询不会返回该结果。你确定吗?
  • 345的电话号码既是9876又是空...?这张桌子的钥匙是……?如果电话号码根据定义是唯一的,则它需要一个 ID,因为...?我认为您需要先修复数据,然后才能从中获得任何明智的结果。

标签: sql database oracle join


【解决方案1】:
your query do not return that results.

很可能您的 phoneperson 表格与您预期的不同。

您应该截断这些表并重新插入数据。然后重新执行您的查询。

 truncate table  Person ; 

truncate table  Phone ; 

 insert into person
 select 1234 ,12 from dual union all
 select 345, 10  from dual union all
 select 43  ,   33   from dual union all
 select 55 ,  27  from dual ;

 commit;

  insert into phone
 select 12 ,  null from dual union all
 select 10 ,  9876 from dual union all
 select  33  ,  9654 from dual union all
 select  27  ,null from dual ;


 commit;

 select t1.person_id, t2.phone_id 
    from person t1
    left join  phone t2
    on t1.phone_id=t2.phone_id;

【讨论】:

  • 为什么不呢?如果你插入这些行然后你的查询得到 4 行
  • data 可以为 null ,但结果是我们预期的正确
【解决方案2】:

您的查询运行良好,因为我已经检查了动态创建表,试试这个,直接在您的查询窗口中运行:

DECLARE @persons TABLE (
person_id INT,
phone_id INT )

DECLARE @phones TABLE (
phone_id INT,
phonenumber BIGINT )


INSERT INTO @persons VALUES(1234,12),(345,10),(43,33),(55,27)
INSERT INTO @phones VALUES(12,null),(10,9876),(33,9654),(27,null)

SELECT * FROM @persons 
SELECT * FROM @phones 

select t1.person_id, t2.phone_id 
from @persons t1
left join
@phones t2
on t1.phone_id=t2.phone_id;

如果你需要删除包含null的条目,你可以在最后使用条件:

WHERE 'column_name' IS NOT NULL

或者如果你想用空白或某个值替换 null,你可以使用:

ISNULL(column_name,'replacement_value') AS new_col_name

【讨论】:

    【解决方案3】:
    WITH actual_phones AS
         ( SELECT phone_id, phone_number
             FROM phone
            WHERE phone_number IS NOT NULL )
    SELECT person_id, phone_number 
      FROM person NATURAL JOIN actual_phones
    UNION
    SELECT person_id, null AS phone_number 
      FROM person
     WHERE phone_id NOT IN ( SELECT phone_id
                                FROM actual_phones );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-09
      • 2019-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多