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

如何从Snomed Postgres SQL数据库提取概念的亲属关系

解决SNOMED CT数据库中查询亲属概念的问题

我来帮你梳理下如何在PostgreSQL的SNOMED CT库中查询特定概念的父、祖父、子、孙概念——核心是利用SNOMED的Is a层级关系(这是构建整个术语体系的基础),下面一步步来:

先明确核心表关联逻辑

SNOMED CT导入后,你需要关注两个核心表:

  • concept:存储所有概念的基本信息,concept_id是唯一标识,active字段标记该概念是否处于有效状态。
  • relationship:存储概念间的各种关系,其中**type_id = 116680003**对应SNOMED标准的「Is a」(从属)关系,这是我们查询层级亲属的关键。

在「Is a」关系中:

  • source_id是子概念的ID,destination_id是父概念的ID(比如「肺癌(93880001)」Is a「恶性肺肿瘤」,所以source_id=93880001,destination_id=父概念ID)

1. 查询直接父概念(上位词)

要获取肺癌的直接父概念,我们需要关联relationship和concept表,过滤有效关系和概念:

SELECT 
    c.concept_id AS parent_concept_id,
    c.fsn AS parent_concept_name
FROM 
    relationship r
JOIN 
    concept c ON r.destination_id = c.concept_id
WHERE 
    r.source_id = 93880001  -- 你的目标概念ID(肺癌)
    AND r.type_id = 116680003  -- Is a关系
    AND r.active = true  -- 只取有效关系
    AND c.active = true;  -- 只取有效概念

2. 查询祖父概念(父概念的父)

可以用递归CTE来实现多层级向上查询,这样不仅能查祖父,还能扩展到任意层级的祖先:

WITH RECURSIVE ancestor AS (
    -- 初始层:直接父概念
    SELECT 
        r.destination_id AS ancestor_id,
        1 AS depth
    FROM 
        relationship r
    WHERE 
        r.source_id = 93880001
        AND r.type_id = 116680003
        AND r.active = true
    UNION ALL
    -- 递归层:向上找父的父
    SELECT 
        r.destination_id AS ancestor_id,
        a.depth + 1 AS depth
    FROM 
        relationship r
    JOIN 
        ancestor a ON r.source_id = a.ancestor_id
    WHERE 
        r.type_id = 116680003
        AND r.active = true
)
SELECT 
    c.concept_id AS grandparent_id,
    c.fsn AS grandparent_name
FROM 
    ancestor a
JOIN 
    concept c ON a.ancestor_id = c.concept_id
WHERE 
    a.depth = 2  -- depth=2就是祖父,depth=3是曾祖父,以此类推
    AND c.active = true;

3. 查询直接子概念(下位词)

子概念的查询逻辑和父概念相反:在「Is a」关系中,子概念的source_id是自己,destination_id是目标概念(肺癌):

SELECT 
    c.concept_id AS child_concept_id,
    c.fsn AS child_concept_name
FROM 
    relationship r
JOIN 
    concept c ON r.source_id = c.concept_id
WHERE 
    r.destination_id = 93880001  -- 目标概念ID(肺癌)
    AND r.type_id = 116680003
    AND r.active = true
    AND c.active = true;

4. 查询孙概念(子概念的子)

同样用递归CTE向下查询:

WITH RECURSIVE descendant AS (
    -- 初始层:直接子概念
    SELECT 
        r.source_id AS descendant_id,
        1 AS depth
    FROM 
        relationship r
    WHERE 
        r.destination_id = 93880001
        AND r.type_id = 116680003
        AND r.active = true
    UNION ALL
    -- 递归层:向下找子的子
    SELECT 
        r.source_id AS descendant_id,
        d.depth + 1 AS depth
    FROM 
        relationship r
    JOIN 
        descendant d ON r.destination_id = d.descendant_id
    WHERE 
        r.type_id = 116680003
        AND r.active = true
)
SELECT 
    c.concept_id AS grandchild_id,
    c.fsn AS grandchild_name
FROM 
    descendant d
JOIN 
    concept c ON d.descendant_id = c.concept_id
WHERE 
    d.depth = 2  -- depth=2是孙概念,depth=3是曾孙,以此类推
    AND c.active = true;

额外提示

  • 如果你需要查询所有祖先/后代(不限层级),只需要去掉CTE中的depth过滤条件即可。
  • 确保始终过滤active = true的记录,SNOMED CT包含很多历史废弃的概念和关系,避免查询到无效数据。
  • fsn字段是「 Fully Specified Name」(完全限定名),是SNOMED概念的标准唯一名称,如果你需要更友好的名称,也可以关联description表并过滤type_id = 900000000000003001(Preferred Term)来获取常用名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:06:15