繁体   English   中英

根据跨多个列的第一个可用非空值连接两个表

[英]Join two tables based on first available non-null value across multiple columns

我在 BigQuery 中有 2 个不同的表,一个详细说明了我的组织的层次结构,另一个表包含不同实体的计划值。 在我进一步解释之前,这里是表格的样子:

表 A - 层次结构此表是在每个仓库的粒度级别定义的。 这本质上是一个扁平化的层次结构(仓库 -> 地区 -> 城市 -> State -> 国家)

国家 State 城市 仓库
C1 S1 CY1 D1 WH1
C1 S1 CY1 D1 WH2
C1 S1 CY1 D2 WH3
C1 S1 CY1 D2 WH4
C1 S1 CY2 D3 WH5
C1 S1 CY2 D3 WH6
... ... ... ... ...

这是另一张表:表 B - 计划值

频率 期间开始 期末 计划金额 领土
最大传输距离 01/01/2022 01/31/2022 500 WH1
年初至今 01/01/2022 01/31/2022 790 WH1
... ... ... ... ...
最大传输距离 12/01/2022 12/31/2022 340 WH1
年初至今 12/01/2022 12/31/2022 1790 WH1
最大传输距离 01/01/2022 01/31/2022 1500 D1
年初至今 01/01/2022 01/31/2022 1800 D1
... ... ... ... ...
最大传输距离 12/01/2022 12/31/2022 1200 D1
年初至今 12/01/2022 12/31/2022 6600 D1

我需要按以下方式加入表 A 和表 B 以创建一个新表(表 C ):

  1. 驱动表是Table A。
  2. 表 B 包含表 B 中仓库、地区、城市等的计划值。但是,它可能包含在任何级别定义的这些计划值 - 有时在仓库级别,有时仅在国家级别。
  3. 对于表 A 中的每个仓库,表 C 必须具有表 B中尽可能最细粒度的相应计划值。 -- 例如,表 B 已有仓库 WH1 的计划值,但没有WH2 的计划值。 因此,对于 WH1,表 C 显示了表 B 中定义的计划值。但是对于 WH2,表 C 必须改为显示学区 (D1) 的计划值。 如果地区级别值不可用,则必须跳到下一个可用级别(一直到国家级别)。

有谁能帮助我了解创建这种类型的连接的逻辑吗?

我想不出解决这个问题的逻辑方法,因为我对 SQL 还很陌生。我的方法是在每个级别创建多个左连接,然后使用合并,但我担心这会创建重复值。

首先,我从表 B 的PeriodStart列中提取所有日期。 所以每个月应该有一行值。 如果您想连续申请多个,请按月拆分(unnest)。 表 A 是为表 B 中的每个日期编写的。 对于表 B 中的每个条目,脚本将采用每月和地区的最大值。 如果本月在territory和仓库之间存在任何匹配,则采用表 B 中这些数据集中的PlanAmount最大值。 否则 ( ifnull ) 检查districtterritory之间的匹配。

with tblA as (select "C1" Country, "S1" State, "CY"|| (1+div(x,4)) City, "D"|| (1+div(x,2)) District, "WH"||x   Warehouse from unnest([1,2,3,4,5,6]) x),
tblB as (Select date("2022-01-01") PeriodStart, 500 PlanAmount, "WH1" Territory
UNION ALL SELECT date("2022-12-01"), 340, "WH1"
UNION ALL SELECT date("2022-12-01"), 1500, "D1"

),
months as (Select * from unnest(generate_date_array(  (Select min(PeriodStart) from tblB), (Select max(PeriodStart) from tblB),interval 1 month ))  as date_month ) ##generate all months in between
,
month_list as (Select distinct PeriodStart as date_month from tblB )

 
SELECT
date_month,country,state,city,District,
ifnull(ifnull(max(WHplan),max(Distplan)),max(Stateplane)) as plan 

from(
Select date_month, tblA.* ,
Wh.PlanAmount as WHplan,
Dist.PlanAmount as Distplan,
State.PlanAmount as Stateplane

from tblA,
#months # generate all months in between OR use:
month_list

left join  tblB WH
on tblA.Warehouse=WH.Territory and date_month=WH.PeriodStart

left join  tblB Dist
on tblA.District=Dist.Territory and date_month=Dist.PeriodStart

left join  tblB State
on tblA.District=State.Territory and date_month=State.PeriodStart
)
group by 1,2,3,4,5

请告知您的数据集是否太大而无法连接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM