You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BigQuery中UPDATE子查询用UNION ALL报错的解决方法

问题:BigQuery UPDATE语句添加UNION ALL后报错的解决方法

问题场景

我在BigQuery中通过CLI执行UPDATE语句更新表,初始查询运行正常,但添加UNION ALL后执行失败,报错信息如下:

UPDATE/MERGE must match at most one source row for each target row

初始正常的查询

bq query --use_legacy_sql=false "UPDATE data_set.table_to_update A 
                                SET D_A_AMOUNT = B.D_A_AMOUNT, A_FEE = B.A_FEE, 
                                O_T_AMOUNT = B.O_T_AMOUNT, U_FEE = B.U_FEE, 
                                UPDATED_DATETIME = B.UPDATED_DATETIME, UPDATED_BY = B.UPDATED_BY 
                                    FROM data_set.table_to_update C 
                                    INNER JOIN ( 
                                    SELECT CAST(131.27 AS NUMERIC) AS D_A_AMOUNT, CAST(20.66 AS NUMERIC) AS A_FEE, 
                                    '12345' AS TRANSACTION_KEY, CAST(145871.0 AS NUMERIC) AS O_T_AMOUNT, 
                                    CAST(131.27 AS NUMERIC) AS U_FEE, '2022-09-28 15:30:47' AS UPDATED_DATETIME, 
                                    'APPLE_USER' AS UPDATED_BY, 'P_S_US' AS L_IDENTITY ) B 
                                    ON C.TRANSACTION_KEY = B.TRANSACTION_KEY  WHERE C.L_IDENTITY = 'P_S_US';"

添加UNION ALL后的错误查询

bq query --use_legacy_sql=false "UPDATE data_set.table_to_update A 
                                SET D_A_AMOUNT = B.D_A_AMOUNT, A_FEE = B.A_FEE, 
                                O_T_AMOUNT = B.O_T_AMOUNT, U_FEE = B.U_FEE, 
                                UPDATED_DATETIME = B.UPDATED_DATETIME, UPDATED_BY = B.UPDATED_BY 
                                    FROM data_set.table_to_update C 
                                    INNER JOIN ( 
                                    SELECT CAST(131.27 AS NUMERIC) AS D_A_AMOUNT, CAST(20.66 AS NUMERIC) AS A_FEE, 
                                    '12345' AS TRANSACTION_KEY, CAST(145871.0 AS NUMERIC) AS O_T_AMOUNT, 
                                    CAST(131.27 AS NUMERIC) AS U_FEE, '2022-09-28 15:30:47' AS UPDATED_DATETIME, 
                                    'APPLE_USER' AS UPDATED_BY, 'P_S_US' AS L_IDENTITY 
                                    UNION ALL  
                                    SELECT CAST(134.19 AS NUMERIC) AS D_A_AMOUNT, CAST(21.31 AS NUMERIC) AS A_FEE, 
                                    '987654232' AS TRANSACTION_KEY, CAST(149112.0 AS NUMERIC) AS O_T_AMOUNT, 
                                    CAST(134.19 AS NUMERIC) AS U_FEE, '2022-09-28 15:30:47' AS UPDATED_DATETIME, 
                                    'APPLE_USER' AS UPDATED_BY, 'P_S_US' AS L_IDENTITY) B 
                                    ON C.TRANSACTION_KEY = B.TRANSACTION_KEY  WHERE C.L_IDENTITY = 'P_S_US';"

错误原因

BigQuery的UPDATE语句要求目标表的每一行最多只能匹配到源数据中的一行。你的查询中存在不必要的自关联(同时引用data_set.table_to_update作为A和C),这种写法可能导致目标行和源数据产生一对多的匹配关系,触发报错。另外如果UNION ALL后的子查询中存在重复的TRANSACTION_KEY,也会导致同样的问题。

修正方案

方案1:简化查询,移除不必要的自关联

直接让目标表和UNION ALL后的子查询关联,避免重复匹配:

bq query --use_legacy_sql=false "UPDATE data_set.table_to_update A
SET D_A_AMOUNT = B.D_A_AMOUNT, A_FEE = B.A_FEE,
O_T_AMOUNT = B.O_T_AMOUNT, U_FEE = B.U_FEE,
UPDATED_DATETIME = B.UPDATED_DATETIME, UPDATED_BY = B.UPDATED_BY
FROM (
    SELECT CAST(131.27 AS NUMERIC) AS D_A_AMOUNT, CAST(20.66 AS NUMERIC) AS A_FEE,
    '12345' AS TRANSACTION_KEY, CAST(145871.0 AS NUMERIC) AS O_T_AMOUNT,
    CAST(131.27 AS NUMERIC) AS U_FEE, '2022-09-28 15:30:47' AS UPDATED_DATETIME,
    'APPLE_USER' AS UPDATED_BY, 'P_S_US' AS L_IDENTITY
    UNION ALL  
    SELECT CAST(134.19 AS NUMERIC) AS D_A_AMOUNT, CAST(21.31 AS NUMERIC) AS A_FEE,
    '987654232' AS TRANSACTION_KEY, CAST(149112.0 AS NUMERIC) AS O_T_AMOUNT,
    CAST(134.19 AS NUMERIC) AS U_FEE, '2022-09-28 15:30:47' AS UPDATED_DATETIME,
    'APPLE_USER' AS UPDATED_BY, 'P_S_US' AS L_IDENTITY
) B
ON A.TRANSACTION_KEY = B.TRANSACTION_KEY 
WHERE A.L_IDENTITY = 'P_S_US';"

方案2:确保源数据无重复(针对可能存在重复TRANSACTION_KEY的情况)

如果UNION ALL后的子查询中可能存在重复的TRANSACTION_KEY,可以通过窗口函数筛选唯一行,确保每个TRANSACTION_KEY只对应一条更新数据:

bq query --use_legacy_sql=false "UPDATE data_set.table_to_update A
SET D_A_AMOUNT = B.D_A_AMOUNT, A_FEE = B.A_FEE,
O_T_AMOUNT = B.O_T_AMOUNT, U_FEE = B.U_FEE,
UPDATED_DATETIME = B.UPDATED_DATETIME, UPDATED_BY = B.UPDATED_BY
FROM (
    SELECT *, 
           ROW_NUMBER() OVER(PARTITION BY TRANSACTION_KEY ORDER BY UPDATED_DATETIME DESC) AS rn
    FROM (
        SELECT CAST(131.27 AS NUMERIC) AS D_A_AMOUNT, CAST(20.66 AS NUMERIC) AS A_FEE,
        '12345' AS TRANSACTION_KEY, CAST(145871.0 AS NUMERIC) AS O_T_AMOUNT,
        CAST(131.27 AS NUMERIC) AS U_FEE, '2022-09-28 15:30:47' AS UPDATED_DATETIME,
        'APPLE_USER' AS UPDATED_BY, 'P_S_US' AS L_IDENTITY
        UNION ALL  
        SELECT CAST(134.19 AS NUMERIC) AS D_A_AMOUNT, CAST(21.31 AS NUMERIC) AS A_FEE,
        '987654232' AS TRANSACTION_KEY, CAST(149112.0 AS NUMERIC) AS O_T_AMOUNT,
        CAST(134.19 AS NUMERIC) AS U_FEE, '2022-09-28 15:30:47' AS UPDATED_DATETIME,
        'APPLE_USER' AS UPDATED_BY, 'P_S_US' AS L_IDENTITY
    )
) B
ON A.TRANSACTION_KEY = B.TRANSACTION_KEY 
WHERE A.L_IDENTITY = 'P_S_US' AND B.rn = 1;"

注:ROW_NUMBER()会按UPDATED_DATETIME倒序排序,取每个TRANSACTION_KEY的最新行作为更新源,你可以根据实际需求调整排序规则。


内容的提问来源于stack exchange,提问作者nmr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:50:29