当行没有匹配的 LEFT JOIN 时,BigQuery 正在创建一个 NULL 结构

Posted

技术标签:

【中文标题】当行没有匹配的 LEFT JOIN 时,BigQuery 正在创建一个 NULL 结构【英文标题】:BigQuery is creating a STRUCT of NULLs when a row has no matching LEFT JOIN 【发布时间】:2020-11-27 07:45:48 【问题描述】:

我有一个名为models 的表。我有另一个名为labelled_data 的表,其中包含modelIdclassId。对于models 中的每一行,我需要计算每个classIdlabelled_data 中出现的次数。

以下 BigQuery 结果的列 classARRAYSTRUCTs。

WITH labelled_data AS(
  SELECT
    modelId,
    classId,
    COUNT(*) as count 
  FROM `abc.xyz.labelled_data`
  GROUP BY 1, 2
)

SELECT
  m.id,
  ARRAY_AGG(
    STRUCT(ld.classId AS id, ld.count)
  ) AS class,
FROM `abc.xyz.models` m
LEFT JOIN labelled_data AS ld ON ld.modelId = m.id
GROUP BY 1

问题在于,如果modelslabelled_data 之间没有匹配的LEFT JOIN,则class 包含一个STRUCT 元素,其元素为NULL

以下是 JSON 格式的大多数行的样子:


    "id": "43A4BBA0-7D3D-466B-B893-CE1397223EB6",
    "class": [
      
        "id": "F0CD7177-2608-4DA3-90F4-69DF435E3C3B",
        "count": "42"
      ,
      
        "id": "25FB2670-FBA8-4961-B4BC-535776FDE6D3",
        "count": "40"
      
    ]

这是一个有问题的行:


    "id": "428E6D3C-98A3-4B9E-BB50-DCD589C6E321",
    "class": [
      
        "id": null,
        "count": null
      
    ]

我希望得到的结果是:


    "id": "428E6D3C-98A3-4B9E-BB50-DCD589C6E321",
    "class": null

请注意,我不能从结果中排除该行。关于如何实现这一点的任何想法?

【问题讨论】:

【参考方案1】:

您可以使用case 表达式来确保至少有一个匹配行:

WITH (...)
SELECT
    m.id,
    CASE WHEN COUNT(ld.modelid) > 0
        THEN ARRAY_AGG(STRUCT(ld.classId AS id, ld.count)) 
    END AS class,
FROM `abc.xyz.models` m
LEFT JOIN labelled_data AS ld ON ld.modelId = m.id
GROUP BY 1

【讨论】:

以上是关于当行没有匹配的 LEFT JOIN 时,BigQuery 正在创建一个 NULL 结构的主要内容,如果未能解决你的问题,请参考以下文章