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

PySpark中IN子查询报错修复:IN/EXISTS子查询仅可用于Filter/Join

修复PySpark中CASE WHEN里IN子查询的报错问题

这个错误是因为PySpark SQL不支持在CASE WHEN的条件判断里直接使用IN子查询,这类子查询只能用在WHERE(Filter)或者JOIN关联逻辑中。下面给两种可行的修复方案:

方案一:将子查询结果转为静态列表(适合小数据集)

先查询出campanhas表中所有的PGTO值,收集成一个本地列表,再直接把这个列表写到CASE WHEN的IN条件里:

  1. 先获取PGTO的去重列表:
# 收集campanhas表中所有PGTO的去重值
pgto_values = spark.sql("SELECT DISTINCT PGTO FROM campanhas").rdd.map(lambda row: row[0]).collect()
# 转成SQL兼容的字符串格式(比如'val1','val2')
pgto_str = "','".join(pgto_values)
  1. 把生成的字符串拼到你的SQL语句中:
CASE
WHEN
MEIO IN ('CARTÃO A','CARTÃO ML','Cartão C') 
AND PGTO IN ('{}') 
THEN 'GH'
-- 可根据需求添加ELSE分支
ELSE 'OTHER'
END

注意:这种方法只适合campanhas表数据量不大的情况,因为collect()会把数据拉到Driver节点,数据量太大可能导致内存问题。

方案二:用JOIN关联表来判断存在性(适合大数据集)

通过左连接或者左半连接,把campanhas表的PGTO关联到主表,生成一个标志位来判断PGTO是否存在,再在CASE WHEN里用这个标志位:

WITH main_with_flag AS (
    SELECT 
        t.*,
        -- 关联成功说明PGTO在campanhas里存在
        CASE WHEN c.PGTO IS NOT NULL THEN 1 ELSE 0 END AS pgto_exists
    FROM your_main_table t
    LEFT JOIN campanhas c ON t.PGTO = c.PGTO
)
SELECT
    *,
    CASE
        WHEN MEIO IN ('CARTÃO A','CARTÃO ML','Cartão C') 
        AND pgto_exists = 1
        THEN 'GH'
        ELSE 'OTHER'
    END AS your_target_column
FROM main_with_flag

如果只需要保留PGTO存在的记录,可以用LEFT SEMI JOIN替换LEFT JOIN,这样不需要生成标志位,直接在WHERE里过滤;但如果要保留所有主表记录,还是用左连接加标志位更合适。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:18:39