【问题标题】:Why does Spark Analyzer report "Correlated scalar subqueries must be Aggregated" in Case?为什么 Spark Analyzer 在案例中报告“必须聚合相关标量子查询”?
【发布时间】:2018-05-29 04:45:11
【问题描述】:

使用spark-sql 的测试由于以下错误而失败:

必须聚合相关的标量子查询

失败的 SQL 查询的相关部分:

COALESCE(
    CASE WHEN ndc_code IN 
    (SELECT CODE FROM BOC_MED_METADATA WHERE CODE_TYPE = 'ndc')
      THEN '180'
    END,
    CASE WHEN hcpcs_code IN 
    (SELECT CODE FROM BOC_MED_METADATA WHERE CODE_TYPE = 'hcpcs')
      THEN '180'
    END,
    med_order_end_dttm,
    CASE WHEN days_supply IS NOT NULL
      THEN
        CASE
          WHEN discontinued AND (med_order_recorded_dttm BETWEEN medication_start AND start_plus)
            THEN med_order_recorded_dttm
          WHEN discontinued AND (med_order_recorded_dttm > start_plus)
            THEN start_plus
          WHEN NOT discontinued
            THEN start_plus
        END
    END,
    medication_start
  )

coalesce 中的前两个cases 是我添加的,导致测试失败。我相信这是因为子查询将如何返回多行,但我不确定如何解决这个问题。任何帮助表示赞赏。如果有什么不同,这个SQL 只是在 Spark 中运行以进行测试,它实际上是在生产中的雪花仓库上运行的。

【问题讨论】:

标签: scala apache-spark apache-spark-sql


【解决方案1】:

看到错误我很困惑,因为我看不出子查询如何被认为是相关的。它们之间的关联是什么?

无论如何,要消除错误(我认为在执行查询之前的分析时发生)是使用任何标准聚合函数来确保 Spark Analyzer 查询确实只返回单行和单行列或根本没有行(这将给出null 作为结果)。

您可以使用firstmax 标准聚合函数,如下所示:

SELECT first(CODE) FROM BOC_MED_METADATA WHERE CODE_TYPE = 'ndc'

我认为 Spark 不应该报告异常,因为我找不到任何相关查询,并且使用 SQL IN 应该真正接受来自子查询的任意数量的值。我很困惑。

【讨论】:

    【解决方案2】:

    如果这个代码:

    CASE WHEN ndc_code IN 
                  (SELECT CODE FROM BOC_MED_METADATA WHERE CODE_TYPE = 'ndc')
         THEN '180'
    

    正在生成表单错误

    必须聚合相关的标量子查询

    并且错误消息是准确的,那么表中缺少CODECODETYPE。所以,我的第一个建议是限定所有列名:

    CASE WHEN ndc_code IN 
                  (SELECT bmm.CODE FROM BOC_MED_METADATA bmm WHERE bmm.CODE_TYPE = 'ndc')
         THEN '180'
    

    这应该返回一个错误,即找不到一列或其他列。

    【讨论】:

    • 我对列进行了限定,但仍然遇到相同的错误。这是堆栈跟踪的样子:Filter (CODE#479 = outer(ndc_code#532)) +- SubqueryAlias boc_med_metadata +- Relation[id#478L,code#479,code_type#480,active_window#481] parquet
    【解决方案3】:

    不要使用IN,而是在前两个CASE 语句中使用EXISTS。试试这个:

    COALESCE(
        CASE WHEN EXISTS( SELECT 1 FROM BOC_MED_METADATA WHERE CODE_TYPE = 'ndc' AND CODE = ndc_code) 
          THEN '180'
        END,
        CASE WHEN EXISTS( SELECT 1 FROM BOC_MED_METADATA WHERE CODE_TYPE = 'hcpcs' AND CODE = hcpcs_code)
          THEN '180'
        END,
        med_order_end_dttm,
        CASE WHEN days_supply IS NOT NULL
          THEN
            CASE
              WHEN discontinued AND (med_order_recorded_dttm BETWEEN medication_start AND start_plus)
                THEN med_order_recorded_dttm
              WHEN discontinued AND (med_order_recorded_dttm > start_plus)
                THEN start_plus
              WHEN NOT discontinued
                THEN start_plus
            END
        END,
        medication_start
      )
    

    如果上述方法失败,请尝试使用表名限定 ndc_codehcpcs_code

    【讨论】:

      猜你喜欢
      • 2019-08-23
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      • 1970-01-01
      • 2020-11-21
      • 1970-01-01
      相关资源
      最近更新 更多