加入联盟

时间:2019-04-22 20:00:22

标签: sql google-bigquery

我认为我已经接近解决方案,但还不完全解决。我有两个表,如果存在给定的ID,我想加入该表,但是如果该ID不存在,则要推迟到另一列作为连接条件。

类似的东西:

T1:
session, ID, path
1001, 1, homepage
1001, NULL, about


T2:
ID, path, type
1, homepage, A
2, about, Z

具有所需的结果:

session, ID, path, type
1001, 1, homepage, A
1001, 2, about, Z

我已经尝试过:

select * from t1 inner join t2 
on (t1.id = t2.id) or (t1.path = t2.path)

但这会产生一些意外的重复。我想做类似的事情

select * from t1 inner join t2
on coalesce(t1.id, t1.path) = t2.id

但这不能正常工作,因为该路径不会映射到另一个表中的ID。

有什么想法或建议吗?

3 个答案:

答案 0 :(得分:1)

您需要一个默认值。这是一种使用两个left join的方法:

select t2.*, coalesce(t1.path, t1d.path) as path
from t2 left join
     t1 
     on t1.id = t2.id left join
     t1 t1d
     on t1d.id is null;

答案 1 :(得分:0)

以下示例适用于BigQuery标准SQL

#standardSQL
WITH `project.dataset.table1` AS (
  SELECT 1001 session, 1 id, 'homepage' path UNION ALL
  SELECT 1001, NULL, 'about'
), `project.dataset.table2` AS (
  SELECT 1 id, 'homepage' path, 'A' type UNION ALL
  SELECT 2, 'about', 'Z' 
)
SELECT 
  session,
  IFNULL(t1.id, t2.id) id, 
  IFNULL(t1.path, t2.path) path, 
  type
FROM `project.dataset.table1` t1
JOIN `project.dataset.table2` t2
ON (t1.id = t2.id) OR (t1.path = t2.path)

有输出

Row session id  path        type     
1   1001    1   homepage    A    
2   1001    2   about       Z      

我意识到,仅当path中的一个或两个均为NULL时,才可能要基于id列加入。在这种情况下,您的ON子句应如下所示

ON t1.id = t2.id 
OR (
  (t1.id IS NULL OR t2.id IS NULL) 
  AND t1.path = t2.path
)

答案 2 :(得分:0)

我能想到的最好的方法是:

select
    t1.session,
    coalesce(t1.ID, t2.ID) as ID,
    t2.path,
    t2.type
from
    t1
    inner join t2 on
        (t1.ID = t2.ID) or
        (t1.ID is null and t1.path = t2.path)

但是,这可能仍然会产生不必要的重复。我无法判断您的数据设计,但是如果结果重复,则可能是由于表t1和/或t2中有问题的(重复的和/或模棱两可的)数据引起的。

这也让我感到震惊,因为问题ID在表t1中显然可以为NULL。从我的角度来看,这意味着表t1t2之间的关系可以被认为是“可选的”。如果不是,最好将表ID中的字段t1定义为必需值。