【问题标题】:Comparison of Columns between two tables with different filters比较具有不同过滤器的两个表之间的列
【发布时间】:2022-11-21 08:20:27
【问题描述】:

我有以下代码用于比较不同表中的两列,如果我在下面的代码中没有任何 where 子句/过滤器,代码几乎可以完美运行。

如果我添加 where 子句,我确实会得到我不想看到的额外行。

with source1 as (
select 
b.id, 
b.qty, 
a.price 
from <table> as a
,unnest <details> as b
 where b.status != 'canceled'
),

source2 as (
select id_, qty_, price_  from <table2>
where city != 'delhi'
) 

select *
from source1 s1
full outer join source2 s2
on id = id_
where format('%t', s1) != format('%t', s2)

以下是示例数据:

s1:

id  qty   price   status
1   100 (null)    canceled
2   0     100       done
3   0      80       canceled
4   50     90       done
5   20    100       done
6   20    100       done
7   80     80       done
8   100   100       canceled
9   40     0        done
10  11     22       done
11  40     40       done
12  null   90       done

s2:

id_ qty_    price_  city_
1   100     200     ny
2   0       100     ny
3   0        80     ny
4   50       80     ny
5   40      100     ny
6   40       40     ny
7   200     200  delhi
8   100     100  delhi
9   40      100     ny
10  11       22  delhi
12  11       11     ny
13  90       80     NY

预期成绩:

id  qty    price    status       id_    qty_    price_  city_
4   50        90    done          4       50    80      ny
5   20       100    done          5       40    100     ny
6   20       100    done          6       40    40      ny
9   40         0    done          9       40    100     ny
11  40        40    done       null     null    null    null
12  null      90    done         12       11    11      ny
null null   null    null         13       90    80      ny
  • 一般来说,我想要所有在任何列中至少有一个不匹配的行(数量、价格、状态)但仅当状态未取消或城市不等于德里时,并在一行中显示每列的两个表 (s1,s2) 的值(如预期结果所示)

  • 如果一行存在于一个表中而不存在于另一个表中并且没有status = canceledcity = delhi,那么它应该显示出来

  • 如果 city != delhistatus != canceled 以及 (qty,price,status) 的值相同,那么,我想要那排***

目前的问题:

where status != 'canceled' -- *这将从源 1 中排除 cases = canceled 的所有行但我的 source2 仍会显示行状态实际上被取消的地方,并且会带来我不想要的那一行

同样,source2 有一个条件:where city != 'delhi' 而 source1 没有,这将再次显示我不想要的行

如果我在我上面的代码(代码 1 和代码 2)的 select 语句中传递列 statuscity,它将在条件中传递:where format('%t', s1) != format('%t', s2) 所以每次都会有不匹配,因为city 列在 source1 中不存在,而 status one 在 source2 中不存在。生成的字符串/序列号将无法匹配,例如:

s1:

id, qty, price, status
1   10   100   cancelled

s2:

id_ qty_ price_  city
1    10   100    Delhi

where format('%t', s1) != format('%t', s2) 会生成:

(1,10,100,cancelled) != (1,10,100,delhi)

在这种情况下,列具有相同的值(数量、价格、状态),但由于上述问题,该行仍会显示我不想要的行。

问题:

  • 有没有一种方法可以将特定列传递给 format('%t',s2) 部分,而不是传递整个表名,这应该可以解决问题?如果我能以某种方式不让状态和城市成为连载的一部分

  • 在这些情况下,我该如何处理 where 子句/过滤器,现在我每个表只有一个过滤器,但将来可能会有更多。

  • 我怎样才能得到预期的输出?除了这个序列化之外,我宁愿不使用任何其他方法,即格式('%t',s2)(如果可能的话)因为我已经有了大部分代码并且想对其进行调整以涵盖所有情况

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    有没有一种方法可以将特定列传递给部分格式('%t',s2),而不是传递整个表名,这应该可以解决问题?如果我能以某种方式不让状态和城市成为连载的一部分

    只需在下面使用

    where format('%t', (id, qty, price)) != format('%t', (id_, qty_, price_))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2020-01-18
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      相关资源
      最近更新 更多