这个错误的原因非常经典IN子句的占位符(?1)写法在 JPA 原生查询中不支持直接传入集合参数。一、根本原因coalesce(?1, null) is null or ids IN (?1)能工作coalesce(?1, null)把参数当作单个值处理如果?1是null条件为真跳过IN检查如果?1有值比如字符串A,B,Cids IN (A,B,C)在 MySQL 中会被当作字符串比较相当于ids A,B,C语法上是合法的虽然逻辑可能不对?1 is null or ids IN (?1)报错当?1不是null时IN (?1)期望?1是一个集合/数组但 JPA 原生查询中?1只是一个占位符对应一个参数值如果你传入的是ListStringJPA 会尝试把它当作单个参数绑定但IN需要多个值于是报Operand should contain 1 column(s)说白了IN子句需要的是多个值但你只给了一个参数占位符?1。二、为什么coalesce版本能工作参数状态coalesce(?1, null) is null or ids IN (?1)实际效果?1 nulltrue or ...→ 整个条件为true不过滤查询全部 ✅?1 A,B,Cfalse or ids IN (A,B,C)MySQL 把A,B,C当作字符串IN变成ids A,B,C⚠️问题ids IN (A,B,C)在 MySQL 中不会报错但逻辑是错误的——它不等于ids IN (A, B, C)。三、你的写法实际想做什么你想实现的是如果参数为null不过滤如果参数有值按IN匹配。标准的 JPQL/原生 SQL 写法应该是sql-- ✅ 正确写法JPQL WHERE (:ids IS NULL OR score.ids IN (:ids))但前提是必须使用JPQLnativeQuery false而不是原生 SQLnativeQuery true。四、解决方案✅ 方案一改用 JPQL推荐java// 去掉 nativeQuery true Query(SELECT s FROM Score s WHERE (:ids IS NULL OR s.ids IN (:ids))) PageScore findByCondition(Param(ids) ListString ids, Pageable pageable);为什么 JPQL 可以JPA 会识别IN (:ids)中的:ids是集合参数自动展开为IN (?, ?, ?)。✅ 方案二使用MEMBER OFJPQLjavaQuery(SELECT s FROM Score s WHERE (:ids IS NULL OR s.ids MEMBER OF :ids)) PageScore findByCondition(Param(ids) ListString ids, Pageable pageable);✅ 方案三在 Service 层处理如果必须用原生 SQLjavapublic ListScore findByCondition(ListString ids) { if (ids null || ids.isEmpty()) { // 查询全部 return repository.findAll(); } // 用 IN 查询 return repository.findByIdsIn(ids); }✅ 方案四使用FIND_IN_SETMySQL 原生写法sqlWHERE (?1 IS NULL OR FIND_IN_SET(ids, ?1) 0)javaQuery(value SELECT * FROM score WHERE (?1 IS NULL OR FIND_IN_SET(ids, ?1) 0), nativeQuery true) PageScore findByCondition(Param(ids) String idsStr, Pageable pageable);传入idsStr A,B,C用逗号分隔的字符串。缺点FIND_IN_SET无法使用索引数据量大时性能差。✅ 方案五使用IN 动态 SQLMyBatis 方式如果项目允许用 MyBatis 的foreach动态拼接xmlselect idfindByCondition SELECT * FROM score where if testids ! null and ids.size() 0 ids IN foreach collectionids itemid open( separator, close) #{id} /foreach /if /where /select五、为什么coalesce写法会隐藏问题写法实际行为coalesce(?1, null) is null or ids IN (?1)参数为null时跳过参数有值时MySQL 把?1当作字符串IN变成比较不会报错但逻辑可能不对?1 is null or ids IN (?1)参数有值时IN期望多个值但只收到一个直接报错所以coalesce版本不是正确只是不报错但查询结果可能不符合预期。六、总结问题原因解决方案?1 is null or ids IN (?1)报错原生 SQL 中IN不支持单个占位符传集合改用 JPQL 或 Service 层处理coalesce版本能工作IN (?1)被 MySQL 当作字符串比较不报错但逻辑可能错误不要使用这种写法正确做法用 JPQL 的IN (:ids)去掉nativeQuery true建议如果你必须用原生 SQL就在 Service 层判断参数是否为空分别处理如果能用 JPQL就去掉nativeQuery用 JPQL 的IN (:ids)写法。