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

PostgreSQL函数中多值字符串数组NOT IN失效问题求解

问题原因分析

你第二个查询失效的核心问题是:NOT IN不会把带大括号的字符串解析成数组。

在第一个正常工作的查询里,你用了A.inuri = ANY ('{...}')——PostgreSQL会自动把这个带大括号的字符串识别为数组类型,然后检查A.inuri是否等于数组中的任意一个元素,所以多值时能正常匹配。

但第二个查询里的A.inuri NOT IN ('{...}'),PostgreSQL会把整个{...}的内容当作一个单一的字符串值。也就是说,它在检查A.inuri是否等于这个完整的长字符串,而不是检查是否等于其中的某一个路径。单值的时候刚好你的路径和这个字符串完全一致,所以能生效;多值时显然没有任何A.inuri等于这个拼接后的长字符串,所以自然没法排除那三个项。

解决方案

有两种简单的修正方式,根据你的习惯选就行:

方式一:用!= ANY()替代NOT IN(推荐,和第一个场景语法统一)

直接沿用第一个场景的数组语法,把=换成!=即可,PostgreSQL会正确解析数组:

SELECT * 
FROM TableA A 
INNER JOIN TableB B ON A.inuri = B.resource_uri 
INNER JOIN TableI I ON I.resource_id = B.resource_id 
WHERE B.resource_type LIKE '%%' 
  AND outuri = './a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)' 
  AND ("isDeleted" = 'false') 
  AND A.inuri != ANY ( 
    '{./a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6), ./a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)/d(f0576f89-1e0e-4eda-b498-0976f3e19c5c), ./a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)/d(baf1d782-77f8-4372-9601-47a486f0700a)}' 
  )

如果觉得字符串数组可读性差,也可以用ARRAY构造器,更清晰:

AND A.inuri != ANY ( ARRAY[
    './a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)',
    './a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)/d(f0576f89-1e0e-4eda-b498-0976f3e19c5c)',
    './a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)/d(baf1d782-77f8-4372-9601-47a486f0700a)'
] )

方式二:修正NOT IN的参数格式

如果一定要用NOT IN,需要把数组拆成单独的字符串值,而不是包裹在大括号里的单个字符串:

AND A.inuri NOT IN (
    './a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)',
    './a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)/d(f0576f89-1e0e-4eda-b498-0976f3e19c5c)',
    './a/b(d91dae45-9e10-43c5-bf08-f52ec80732d3)/c(ee0cc326-fbaf-4d04-a9a6-31d515dea1f6)/d(baf1d782-77f8-4372-9601-47a486f0700a)'
)
总结

优先推荐方式一,因为它和你第一个场景的语法保持一致,后续维护起来更统一;而且当你需要动态生成数组的时候,用ANY()的数组格式也更方便,不需要额外拆分字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:58:17