Google bigquery BigQuery给出了不一致的结果

Google bigquery BigQuery给出了不一致的结果,google-bigquery,Google Bigquery,有人知道为什么BigQuery会给出不一致的结果吗。我运行了三个不同的查询,它们应该都给出相同的结果,但它们都不同 对于每个用户会话,我只存储设备类型的iOS,所以这是ipad或iphone,还有一个bool,表示用户是否打开或关闭了通知。我已经检查过这些值从不为空,设备类型为“ipad”或“iphone” 但当我运行以下查询时: select (SELECT count(distinct user_id) FROM `session` where notifications = True) +

有人知道为什么BigQuery会给出不一致的结果吗。我运行了三个不同的查询,它们应该都给出相同的结果,但它们都不同

对于每个用户会话,我只存储设备类型的iOS,所以这是ipad或iphone,还有一个bool,表示用户是否打开或关闭了通知。我已经检查过这些值从不为空,设备类型为“ipad”或“iphone”

但当我运行以下查询时:

select (SELECT count(distinct user_id) FROM `session` where notifications = True) + (SELECT count(distinct user_id) FROM `session` where notifications = False)
我的总数是9615。当我跑步时:

select (SELECT count(distinct user_id) FROM `session` where device_type = 'ipad') + (SELECT count(distinct user_id) FROM `session` where device_type = 'iphone')
select count(distinct user_id) FROM `session`
总数是9588。当我跑步时:

select (SELECT count(distinct user_id) FROM `session` where device_type = 'ipad') + (SELECT count(distinct user_id) FROM `session` where device_type = 'iphone')
select count(distinct user_id) FROM `session`
它给我9585。所以9615、9588和9585虽然它们应该是一样的。我已经在多个订单中运行了它们,并尝试在最后一天内过滤掉所有设置的实体

这是什么原因造成的?我没有看到任何逻辑错误,这只是一些大的查询行为吗


谢谢

希望下面的简化示例能准确地说明为什么会发生这种情况——主要是因为不同的原因

#standardSQL
WITH `session` AS (
  SELECT 1 user_id, TRUE notifications, 'ipad' device_type UNION ALL
  SELECT 1 user_id, TRUE notifications, 'iphone' device_type UNION ALL
  SELECT 2 user_id, TRUE notifications, 'ipad' device_type UNION ALL
  SELECT 2 user_id, FALSE notifications, 'iphone' device_type 
)
SELECT 
  (SELECT COUNT(DISTINCT user_id) FROM `session` WHERE notifications = TRUE) + 
  (SELECT COUNT(DISTINCT user_id) FROM `session` WHERE notifications = FALSE) AS query1,
  (SELECT COUNT(DISTINCT user_id) FROM `session` WHERE device_type = 'ipad') + 
  (SELECT COUNT(DISTINCT user_id) FROM `session` WHERE device_type = 'iphone') AS query2,
  (SELECT COUNT(DISTINCT user_id) FROM `session`) AS query3
有输出

Row query1  query2  query3   
1   3       4       2        
而下面的版本则不同

#standardSQL
WITH `session` AS (
  SELECT 1 user_id, TRUE notifications, 'ipad' device_type UNION ALL
  SELECT 1 user_id, TRUE notifications, 'iphone' device_type UNION ALL
  SELECT 2 user_id, TRUE notifications, 'ipad' device_type UNION ALL
  SELECT 2 user_id, FALSE notifications, 'iphone' device_type 
)
SELECT 
  (SELECT COUNT(user_id) FROM `session` WHERE notifications = TRUE) + 
  (SELECT COUNT(user_id) FROM `session` WHERE notifications = FALSE) AS query1,
  (SELECT COUNT(user_id) FROM `session` WHERE device_type = 'ipad') + 
  (SELECT COUNT(user_id) FROM `session` WHERE device_type = 'iphone') AS query2,
  (SELECT COUNT(user_id) FROM `session`) AS query3  
结果与

Row query1  query2  query3   
1   4       4       4    

BigQuery使用近似聚合来更好地处理大型数据集。如果近似值不适合您的情况,则可以使用精确聚合。默认行为取决于您使用的SQL方言:传统SQL默认为近似值,标准SQL默认为精确值

我假设您使用的是遗留sql,您可以使用EXACT_COUNT_DISTINCT函数来获得精确计数。有关旧版sql count distinct函数的更多信息,请参见此处:


您可以从本文档中找到更多信息

哦,就是这样。谢谢!虽然,也许我说得太快了。我使用的是标准sql,如果您要查找近似数字,那么应该使用“近似计数”(About_COUNT_DISTINCT),而我们实际上就是这样。所以countdistinct X应该根据文档给出精确的结果,如果我没有弄错的话。对于标准sql,默认情况下它应该是精确的distinct count。您是否仔细检查了数据,以避免同一用户id的多个会话具有不同的通知或设备类型字段值?这会导致同一个用户id被计数多次。嘿,是的,就是这样。我开始深入挖掘导致数字不匹配的行,你完全正确,一些通知在开始时打开,后来关闭,因此一些用户ID被计数多次。非常感谢!另外,了解“近似计数”很好,因为这已经足够多了!既然你也是芬兰人,如果我们见面的话,我就请你喝杯啤酒!