两列上的 BigQuery 重复数据删除作为唯一键

Posted

技术标签:

【中文标题】两列上的 BigQuery 重复数据删除作为唯一键【英文标题】:BigQuery DeDuplication on two columns as unique key 【发布时间】:2016-07-18 21:46:35 【问题描述】:

我们虔诚地使用 BigQuery,并拥有两个表,它们基本上是由不同的进程并行更新的。我遇到的问题是我们没有表的唯一标识符,目标是尽可能将两个表组合成零重复。唯一标识符是两列组合。

我尝试了各种基于 mysql 的查询,但在 BigQuery 中似乎都没有。所以我在这里发帖寻求帮助。 :)

第 1 步。将“干净”表复制到新的合并表中。

第 2 步。查询“脏”(旧)表并插入任何缺失的条目。

查询尝试 1:

SELECT
  COUNT(c.*)
FROM
  [flash-student-96619:device_data.device_datav3_20160530] AS old
WHERE NOT EXISTS (
  SELECT
    1
  FROM
    [flash-student-96619:device_data_v7_merged.20160530] AS new
  WHERE
    new.dsn = old.dsn
    AND new.timestamp = old.timestamp 
)

错误:错误发生在:6.1 - 10.65。一次只能执行一个查询。

查询尝试 2:

SELECT
  *
FROM
  [flash-student-96619:device_data.device_datav3_20160530]
WHERE
  (dsn, timestamp) NOT IN (
  SELECT
    dsn,
    timestamp
  FROM
    [flash-student-96619:device_data_v7_merged.20160530] 
  )

错误:在第 6 行第 7 列遇到“”、“”、“”。期待:“)”...

老实说,如果我能在一个查询中做到这一点,我会很高兴。我需要从两个表中获取数据,并使用唯一数据创建一个新表。

有什么帮助吗?

【问题讨论】:

【参考方案1】:

类似下面的东西应该可以工作

SELECT * 
FROM (
  SELECT *,
    ROW_NUMBER() OVER(PARTITION BY dsn, timestamp) AS dup
  FROM
    [flash-student-96619:device_data.device_datav3_20160530],
    [flash-student-96619:device_data_v7_merged.20160530] 
) 
WHERE dup = 1  

我建议在外部 SELECT 中使用明确的字段列表而不是 *,这样您就可以从实际输出中省略 dup

【讨论】:

两张桌子怎么样。我不想对一张表本身进行重复数据删除,而是对另一张表进行重复数据删除。我想我可以写一个表,然后重新写一个表...... 这是要遵循的方向 :o) - 无论如何添加了第二个表 - 想法是删除组合数据(来自两个表)并将其写入最终的干净表。希望这就是你想要实现的目标 你着火了,我的朋友。【参考方案2】:

有点晚了,但我想指出您的原始查询使用standard SQL 进行了少量修改(取消选中“显示选项”下的“使用旧版 SQL”框)。我只需将new 更改为其他内容,因为这是保留关键字。例如,这个查询是有效的:

WITH OldData AS (
  SELECT
    x AS dsn,
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp
  FROM UNNEST([1, 2, 3, 4]) AS x),
NewData AS (
  SELECT
    x AS dsn,
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp
  FROM UNNEST([5, 2, 1, 6]) AS x)
SELECT
  COUNT(*)
FROM OldData oldData
WHERE NOT EXISTS (
  SELECT 1
  FROM NewData newData
  WHERE
    newData.dsn = oldData.dsn
    AND newData.timestamp = oldData.timestamp
);
+-----+
| f0_ |
+-----+
|   2 |
+-----+

关于你的第二次尝试,你可以这样做:

WITH OldData AS (
  SELECT
    x AS dsn,
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp
  FROM UNNEST([1, 2, 3, 4]) AS x),
NewData AS (
  SELECT
    x AS dsn,
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp
  FROM UNNEST([5, 2, 1, 6]) AS x)
SELECT
  *
FROM OldData
WHERE
  STRUCT(dsn, timestamp) NOT IN (
  SELECT AS STRUCT
    dsn,
    timestamp
  FROM NewData);
+-----+---------------------+
| dsn |      timestamp      |
+-----+---------------------+
|   3 | 2016-07-21 11:54:08 |
|   4 | 2016-07-21 10:54:08 |
+-----+---------------------+

【讨论】:

以上是关于两列上的 BigQuery 重复数据删除作为唯一键的主要内容,如果未能解决你的问题,请参考以下文章

SQL 根据两列删除重复记录

索引视图的两列上的唯一聚集索引

MySQL计算两列上的唯一值并为每列加入这些计数

两列上的 DENSE_RANK,其中一列是不同的值,另一列是重复的

怎么取消自增列上的聚集索引

MySQL两列唯一键[重复]