繁体   English   中英

如何通过将一个表中的 id 与 bigquery 中另一个表中的多个列中的 id 连接来获取记录以获取大表?

[英]How to get records by joining id in one table with id in multiple columns in another table in bigquery for huge tables?

我有两张桌子emp和prj。 表的列和数据类型如下 Emp 有 EmpNo(INT), EmpITPrj(STR), EmpFinPrj(STR), EmpHRPrj(STR), EmpIntPrj(STR), EmpDate(STR) 和 prj 有 PrjID(STR), PrjStartDate( STR),项目结束日期(STR)。 目标是显示所有符合条件的记录。 .PrjEndDate。

但对于实际的行/列数,该解决方案也应该是可行的。 emp - 2M 行和 1.8k 列和 prj - 10k 行和 100 列。

EmpNo   EmpITPrj    EmpFinPrj   EmpHRPrj    EmpIntPrj   Date
1         IT101       null        null         null     2019-09-01
2         null        Fin101      null         null     2001-06-05
3         null        Fin102      null         null     2005-11-25
4         null        null        null         Int501   2010-10-15
5         null        null        null         Int105   2019-01-10
6         null        null        null         Int444   2015-12-03
7         null        null        HR110        null     2012-08-19
8         IT101       null        null         null     2011-04-24
9         null        null        HR105        null     2005-02-09
10        IT102       null        null         null     2006-07-11



PrjID   PrjStartDate    PrjEndDate
Fin102  10/14/2005      12/14/2005
IT102   07/11/2006      10/30/2006
IT110   11/15/2010      01/31/2011
Int101  01/01/2015      03/31/2015
HR110   05/19/2012      08/19/2012
Int444  01/01/2015      03/01/2015

End Result:
EmpNo   EmpITPrj    EmpFinPrj   EmpHRPrj    EmpIntPrj   EmpDate     PrjID   PrjStartDate    PrjEndDate
3       null        Fin102      null        null        2005-11-25  Fin102  10/14/2005      12/14/2005
10      IT102       null        null        null        2006-07-11  IT102   07/11/2006      10/30/2006
7       null        null        HR110       null        2012-08-19  HR110   05/19/2012      08/19/2012

不确定这是否正是您要查找的内容,但至少在下面消除了直接引用 emp 表中的所有字段。 如果您在 prj 表中涉及多个字段 - 您可以通过应用类似的逻辑来扩展此解决方案

#standardSQL
SELECT *
FROM `bigquery-project-123.emp` AS t1
JOIN `bigquery-project-123.prj` t2 
ON CONCAT('"', t2.PrjID, '"') IN UNNEST(SPLIT(REGEXP_REPLACE(FORMAT('%T', t1), r'^\(|\)$', ''), ', '))
AND SAFE.PARSE_DATE("%Y-%m-%d", t1.EmpDate) BETWEEN 
SAFE.PARSE_DATE("%m/%d/%Y",t2.PrjStartDate) AND SAFE.PARSE_DATE("%m/%d/%Y",t2.PrjEndDate) 

此查询将提供您正在寻找的结果:

#standardSQL
SELECT 
  *
FROM 
  `BQ_TABLE_emp` AS emp
JOIN 
  `BQ_TABLE_prj` AS prj
ON
  prj.PrjID IN (emp.EmpITPrj, emp.EmpFinPrj, emp.EmpHRPrj, emp.EmpIntPrj) AND
  emp.Date BETWEEN prj.PrjStartDate AND prj.PrjEndDate;

为了提高这项工作的性能,我建议明确指定JOIN条件的内容如下:

#standardSQL
SELECT 
  *
FROM 
  `BQ_TABLE_emp` AS emp
JOIN 
  `BQ_TABLE_prj` AS prj
ON
  (prj.PrjID = emp.EmpITPrj OR prj.PrjID = emp.EmpFinPrj OR prj.PrjID = emp.EmpHRPrj OR prj.PrjID = emp.EmpIntPrj) AND
  (emp.Date >= prj.PrjStartDate AND emp.Date <= prj.PrjEndDate);

对于empprj表中分别有 2M 行和 1.8K 的情况,我已经在 BigQuery 中测试了上述解决方案,并且两者都是可行的。 请记住,由于复杂的 JOIN 条件,这种类型的语句通常会导致大量数据操作,从而耗尽可用资源。

暂无
暂无

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

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