如何将列与Google Big Query中的行保持一致

时间:2017-07-20 18:46:25

标签: google-bigquery

我正在进行数据质量检查测试。

我有这个查询来确定源表和目标表之间的任何错误。

select 
count(case when coalesce(x.col1,1) = coalesce(y.col1,1) then null else 1 end) as cnt_col1,
count(case when coalesce(x.col2,"1") = coalesce(y.col2,"1") then null else 1 end) as cnt_col2
from
`DatasetA.Table` x
OUTER JOIN
`DatasetB.Table` y
on x.col1 = y.col1

此查询的输出如下:

col1, col2
null, null
null, null
1, null
null, 1

我需要执行此测试的200个表,cols的数量是动态的。上面的表只有两列,有些有50列。

我已经对表进行了查询,但是我需要将所有测试的输出整合到一个输出中。我的计划是将每个查询符合统一输出,并使用UNION ALL将它们连接在一起。

输出集应该说:

COLUMN, COUNT_OF_ERRORS
cnt_col1, 1
cnt_col2, 1
...
cnt_col15, 0

我的问题是这个。 如何反转枢轴,以便我可以实现我正在寻找的输出。

由于

2 个答案:

答案 0 :(得分:2)

  

如何反转枢轴,以便我可以实现我正在寻找的输出。

假设你有表`data`

col1    col2    col3
----    ----    ----     
null    null    null     
null    null    1    
null    1       1    
1       null    1    
1       null    1    
1       null    1   

你需要反向转动它

column      count_of_errors  
--------    ---------------
cnt_col1    3    
cnt_col2    1    
cnt_col3    5    

下面是BigQuery Standard SQL,正是这个

   
#standardSQL
WITH `data` AS (
  SELECT NULL AS col1, NULL AS col2, NULL AS col3 UNION ALL
  SELECT NULL, NULL, 1 UNION ALL
  SELECT 1, NULL, 1 UNION ALL
  SELECT NULL, 1, 1 UNION ALL
  SELECT 1, NULL, 1 UNION ALL
  SELECT 1, NULL, 1
)
SELECT r.* FROM (
  SELECT 
    [
    STRUCT<column STRING, count_of_errors INT64>
      ('cnt_col1', SUM(col1)),
      ('cnt_col2', SUM(col2)),
      ('cnt_col3', SUM(col3))
    ] AS row
  FROM `data`
), UNNEST(row) AS r   

它很简单且友好,可以调整到初始`data`表中可能包含的任意数量的列 - 您只需要添加相应数量的('cnt_colN', SUM(colN)), - 这可以手动完成,也可以只是编写简单的脚本来生成那些行(或整个查询)

答案 1 :(得分:1)

关于“比较大数据中的2个表”,我不认为做一些联接是最好的方法,因为联接通常很慢,然后你必须处理“外”联接行的情况。 / p>

几年前我在这个主题上工作过(https://community.hortonworks.com/articles/1283/hive-script-to-validate-tables-compare-one-with-an.html),我现在正试图向后移植这些知识,以便将Hive表与BigQuery表进行比较。

我的主要想法之一是使用一些校验和来确保表与另一个完全相同。 这是一个“基本的例子”:

with one_string as(
select concat( sessionid ,'|',referrercode ,'|',purchaseid ,'|',customerid ,'|', cast(bouncerateind as string),'|', cast( productpagevisit as string),'|', cast( itemordervalue as string),'|', cast( purchaseinsession as string),'|', cast( hit_time_gmt as string),'|',datedir ,'|',productcategory ,'|',post_cookies) as bigstring from bidwh2.omniture_2017_03_24_v2
),
shas as(
   select TO_BASE64( sha1( bigstring)) as sha from one_string
),
shas_prefix as(
   select substr( sha, 0 , 1) as prefix, sha from shas
),
shas_ordered as(
    select prefix, sha from shas_prefix order by sha
 ),
results_prefix as(
    select concat( prefix, ' ', TO_BASE64( sha1( STRING_AGG( sha, '|')))) as res from shas_ordered group by prefix
),
results_ordered as(
    select 1 as myall, res from results_prefix order by res
)
select SHA1( STRING_AGG( res, '|')) as sha from results_ordered group by myall;

所以你在2个表中的每个表上都这样做,并比较2个校验和数字。

最后的想法是创建一个Python脚本(尚未完成,我希望我的公司允许我在完成后开源),它将执行以下操作:

  1. 计算某些“存储桶”的行数(具有良好分布的列具有相同校验和的模数为大数字的行组)并比较结果(因为如果数量为0,则无需校验整个表行不匹配)。
  2. 如果计数不匹配,
  3. 直观地显示差异
  4. 使用存储桶/行技术+其他一些“存储桶/列”以类似的方式执行一些校验和,如上例所示。并将所有这些校验和进行比较。
  5. 直观地显示校验和不匹配时的差异
  6. 编辑于03/11/2017 :脚本已完成,可在以下位置找到:https://github.com/bolcom/hive_compared_bq