【问题标题】:BigQuery SQL limit update to one rowBigQuery SQL 限制更新为一行
【发布时间】:2020-07-05 08:18:37
【问题描述】:

我有一个包含三列的BigQuery 表,每一行可以具有与前一行相同的值。

例如:

| col_a | col_b | col_c
+-------+-------+------------
| 123   |   3   | 2019-12-12
| 123   |   3   | 2019-12-12
| 234   |  11   | 2019-10-12

现在我想添加一个名为 col_d 的新列,其中包含一个 UUID。

问题是当我尝试执行UPDATE 命令时,我无法一次只更新一行(因为有些行具有相同的值,而我希望每一行都有不同的 UUID)。

我没有运气尝试的事情:(

限制

UPDATE table 
SET col_d = GENERATE_UUID() 
LIMIT 1

我想获取所有行,然后使用更新命令遍历它们。但 BigQuery 中的 UPDATE 命令没有限制。

ROW_NUMBER

UPDATE table 
SET col_d = ROW_NUMBER() OVER()

但 BigQuery 不允许在 Update 命令中使用解析函数

插入

我可以查询所有行,并使用 UUID 插入它们,然后删除所有没有 UUID 的旧行。这种方法会奏效,这将是我的最后一道关口,但我相信有更好的方法,所以我在这里问。

欢迎任何其他想法或建议。

【问题讨论】:

    标签: sql google-bigquery sql-update


    【解决方案1】:

    以下是 BigQuery 标准 SQL 并为每一行生成不同的 UUID,无论它们多么重复

    UPDATE `project.dataset.table`
    SET col_d = GENERATE_UUID()
    WHERE TRUE   
    

    注意:根据您的“插入然后删除”选项 - 我假设 col_d 已经存在于您的表中 - 否则您将无法像您在 cmets 中提到的那样执行 DELETE FROM table WHERE col_d IS NULL

    【讨论】:

    • 是“真正的地方”是魔法发生的地方吗?这就是导致生成不同 uuid 的原因?
    • BigQuery 中的 WHERE 子句对于 UPDATE 语句是强制性的:o)
    【解决方案2】:

    您可以选择带有 UUID 的数据作为第四列 (col_d),然后将该数据另存为新表。

    SELECT col_ac, col_b, col_c, GENERATE_UUID() AS col_d
    FROM table
    

    这将生成您想要的输出:

    | col_a | col_b | col_c       | col_d
    +-------+-------+-------------+------------------------------------------
    | 123   |   3   | 2019-12-12  | e3784e4d-59bb-433b-a9ac-3df318e0f675
    | 123   |   3   | 2019-12-12  | 430d034a-6292-4f5e-b1b0-0ee5550af3f6
    | 234   |  11   | 2019-10-12  | 3e7e14d2-3077-4030-a704-5a2b7fc3c11e
    

    由于 BigQuery 不允许添加包含传统 SQL 等数据的列,因此以下应创建一个添加了 UUID 值的新表。

    CREATE OR REPLACE TABLE table AS 
    SELECT *, GENERATE_UUID() AS col_d
    FROM table
    

    请注意,表历史记录可能会被删除,因此请先备份。在任何情况下都应该在进行此类更新之前备份数据,因为确实会出现不希望的结果。

    【讨论】:

    • 我所做的是按照您的建议选择带有 GENERATE_UUID 的数据并将其添加到表中。然后当 col_d 为空时,我只是删除了所有行。 SQL: INSERT INTO table SELECT col_a, col_b, col_c, GENERATE_UUID() as col_d; DELETE FROM table WHERE col_d IS NULL;
    【解决方案3】:

    因为有些行具有相同的值,我希望每一行都有不同的 UUID

    这应该做你想做的:

    UPDATE table 
        SET col_d = GENERATE_UUID() 
    

    如果你想更新所有行,我不明白你为什么要使用limit

    也就是说,BigQuery 对 UPDATEs 有限制,因此 fromthehills 建议的 CREATE TABLE 方法似乎更合适。

    【讨论】:

    • 使用您的更新不会为所有行设置相同的 uuid?
    • @Avisho 。 . .该函数应在每一行上重新计算。顺便说一句,这与您接受的答案完全相同相同,但在几个小时前就完成了。 (嗯,它没有where true,但这似乎对这个问题并不重要。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 2022-08-05
    • 1970-01-01
    • 2021-11-07
    • 2021-10-10
    相关资源
    最近更新 更多