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

PostgreSQL中如何查询同时包含指定JSON元素的CI记录

筛选PostgreSQL中JSON数组同时包含指定元素的记录

表结构与数据

select * from ci_grp;

      ci    |                             grp
------------+-------------------------------------------------------------------------------------------
 Ci1        | [{"Name":"TEAM.Virtu"},{"Name":"TECH.LinuxDevice"}]
 Ci2        | [{"Name":"TECH.LinuxDevice"},{"Name":"TEAM.Monitoring"}]
 Ci3        | [{"Name":"TEAM.Noc"},{"Name":"TEAM.Virtu"},{"Name":"TECH.DellEsx"},{"Name":"TECH.SNMP"}]
 Ci4        | [{"Name":"TEAM.Monitoring"},{"Name":"TECH.Postgresql"}]
 Ci5        | [{"Name":"TEAM.Monitoring"},{"Name":"TECH.LinuxDevice"},{"Name":"TECH.ZabbixProxy"}]

需求

获取grp数组中同时包含{"Name":"TECH.LinuxDevice"}和{"Name":"TEAM.Monitoring"}的CI名称(即Ci2和Ci5)。

最优SQL方案

方案1:使用JSON包含操作符@>(性能最优)

如果grp字段是json或jsonb类型,直接用PostgreSQL内置的JSON包含操作符即可,无需展开数组:

SELECT ci
FROM ci_grp
WHERE grp @> '[{"Name":"TECH.LinuxDevice"},{"Name":"TEAM.Monitoring"}]'::json;
  • 说明:@>操作符判断左侧JSON数组是否包含右侧所有指定的JSON对象,匹配逻辑精准且效率高。如果你的grp字段是jsonb类型,还可以创建GIN索引进一步提升查询性能:
    CREATE INDEX idx_ci_grp_jsonb ON ci_grp USING GIN (grp);
    

方案2:展开数组后分组统计(灵活适配复杂场景)

如果需要更复杂的匹配逻辑,可先展开JSON数组,再通过分组计数判断是否同时包含目标元素:

SELECT ci
FROM (
    SELECT ci, json_array_elements(grp)->>'Name' AS grp_name
    FROM ci_grp
) AS grp_elements
WHERE grp_name IN ('TECH.LinuxDevice', 'TEAM.Monitoring')
GROUP BY ci
HAVING COUNT(DISTINCT grp_name) = 2;
  • 说明:先将每个CI对应的grp数组展开为单行记录,筛选出目标的两个分组名称;再按CI分组,统计不同分组名称的数量等于2,即可确认该CI同时包含两个目标元素。

原查询问题分析

你最初的查询将数组展开后,用AND同时匹配两个分组名称,而单行记录仅对应一个分组名称,因此无法满足条件导致无结果。分组统计的方式则通过聚合逻辑解决了这个问题,确保两个元素都存在于同一CI的数组中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:03:24