SQL子查询关联 operand 错误:integer与integer[]不匹配问题
integer = integer[]错误 嘿,我来帮你解决这个查询报错的问题!先理清楚你的场景:你有个带id和amount的数据集,想关联从logs表additional_infos字段里提取出的ID集合,但跑代码时触发了operator does not exist: integer = integer[]的错误,这问题其实很好解决~
为啥会报错?
你写的子查询SELECT array_agg(unnest::int)...最后返回的是一个整数数组,但first_data.id是单个整数。IN子句需要的是一组独立的单个值,而不是一个数组,这就导致了类型不匹配的问题,PostgreSQL自然不认这种操作。
另外提一句:你用REGEXP_MATCHES提取(\d+)=>的方式,可能会误抓嵌套结构里的数字(比如221=>{"network"=>0.0}里的221没问题,但如果嵌套里有数字就会错提),后面我也会给你优化思路。
两种可行的解决写法
写法一:直接提取单个ID(推荐)
把嵌套子句简化,直接提取每个匹配的数字ID转成整数,让子查询返回一行行的单个值,这样IN就能正常工作:
SELECT * FROM first_data WHERE id IN ( -- 取正则匹配到的第一个元素,转成整数 SELECT (unnest(REGEXP_MATCHES(svals, '(\d+)=>', 'g')))[1]::int FROM ( SELECT svals(additional_infos) as svals FROM logs bl ) as s );
这里的关键是:REGEXP_MATCHES返回的是文本数组,[1]用来取出数组里的匹配数字,转成整数后,子查询输出的就是独立的ID值,刚好符合IN的要求。
写法二:用ANY匹配数组
如果你非要保留数组聚合的写法,可以用PostgreSQL支持的= ANY()操作符,判断单个ID是否在数组里:
SELECT * FROM first_data WHERE id = ANY ( SELECT array_agg((unnest(REGEXP_MATCHES(svals, '(\d+)=>', 'g')))[1]::int) FROM ( SELECT svals(additional_infos) as svals FROM logs bl ) as s );
这种写法里,子查询返回的是整数数组,= ANY()会逐一检查id是否是数组中的元素,完美适配类型。
额外优化建议
看你给出的additional_infos格式,它看起来像是PostgreSQL的hstore或者JSON类型?如果是hstore,完全不用正则,用内置函数提取键更准确高效:
SELECT (each(additional_infos)).key::int FROM logs bl -- 只保留纯数字的键 WHERE (each(additional_infos)).key ~ '^\d+$';
这种方式能精准提取顶级的数字ID,不会误抓嵌套结构里的数字,性能也比正则好很多。
内容的提问来源于stack exchange,提问作者delalma

