为什么Spark Analyzer报告"相关的标量子查询必须聚合"如果?

时间:2018-04-24 16:04:57

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

由于以下错误,使用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
  )

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

3 个答案:

答案 0 :(得分:0)

如果这段代码:

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'

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我很难看到错误,因为我不知道子查询是如何被认为是相关的。他们有什么关联?

无论如何,要摆脱错误(我认为在查询执行之前的分析时间发生)是使用任何标准聚合函数,以确保Spark Analyzer只返回一行的查询列或根本没有行(这将导致null)。

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

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

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