【问题标题】:How do i point to default dummy record incase when foreign key is null当外键为空时,我如何指向默认的虚拟记录
【发布时间】:2019-06-26 08:37:28
【问题描述】:

我有查询,我在其中加入多维表以创建事实表。对于外键为空的情况,我想将其指向维度表中添加的默认虚拟记录,以便字段中没有空值。这怎么可能 。请帮忙。

Select 
a.name,
a.id_no,
d.dealer_name,
d.address

from 
contract a
left join dealer b 
on a.con_id=b.con_id

对于上面的示例,当 b.con_id 为 null 并且在这种情况下找不到匹配项时,我想指向添加到经销商表中的默认外键(0)。就像如果 FK 为空,则采用默认 fk 并使用这些记录来填充字段

【问题讨论】:

  • 有必要使用虚拟记录吗? AFAIK 如果您的列为空,您可以使用 COALESCE 指定一个值。
  • 是的。但根据 kimball 数据仓库设计,这将是一种标准做法
  • 从我读到的(假设#43)结果不应该包含空值,所以合并会解决这个问题。
  • 您的表合约是否有 a.con_id = 0 的行?在这种情况下,您可以将加入条件作为 - on a.con_id=COALESCE(b.con_id ,0)

标签: sql join hive foreign-keys


【解决方案1】:

您可以在查询中使用ISNULL()

例如:

select * 
from table1 as a 
left join table2 as b on a.id = ISNULL(b.id, 0)

【讨论】:

  • 小心,这个解决方案永远不会起作用,因为在加入之前应用了 ISNULL。自己测试一下,你会看到的。看我的测试:demo.gethue.com/hue/editor?editor=53578
  • with a as ( select stack(3, 1,'val1', 2,'val2', 3,'val3' ) as (id, val) ), b as ( select stack(3, 0,'val1', 2,'val2', 3,'val3' ) as (id, val) ) select * from a left join b on a.id=nvl(b.id,0) - 这会返回错误的结果。它将以这种方式更新工作
【解决方案2】:

您可以采取确保每个维度表都有一个默认行的方法,例如以-1 作为值:

insert into dim_table (dim_table_id, . . . )
    values (-1, . . . );

然后在大多数数据库中,您可以将引用声明为:

create table other_table (
    . . .,
    dim_table_id int not null default -1 references dim_table(dim_table_id)
    . . .
);

但是,我认为 Hive(尚)不支持列上的 default 值。因此,您可以这样做,但您需要在将新行插入引用表时显式插入 -1

【讨论】:

    【解决方案3】:

    您可以要么将其保留为空您可以将事实记录指向一个虚拟记录,显示它没有引用(id

    【讨论】:

      【解决方案4】:

      您可以用默认值替换未连接的记录,如下所示:

      Select 
      a.name,
      a.id_no,
      case when d.con_id is null then 'Default Name' else d.dealer_name end dealer_name  ,
      case when d.con_id is null then 'Default Address' else d.address  end address
      from 
      contract a
      left join dealer d 
      on a.con_id=d.con_id
      

      或者使用 con_id=0 函数添加第二个连接:

      Select 
      a.name,
      a.id_no,
      case when d.con_id is null then d0.dealer_name else d.dealer_name end dealer_name  ,
      case when d.con_id is null then d0.address     else d.address     end address
      from 
      contract a
      left join dealer d on a.con_id=d.con_id
      left join dealer d0 on d.con_id is null and d0.con_id=0
      

      【讨论】:

        猜你喜欢
        • 2016-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-15
        • 1970-01-01
        • 1970-01-01
        • 2013-12-27
        相关资源
        最近更新 更多