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

含UNION的SPARQL查询去重:仅保留有值的孪生实体结果

解决WDQS孪生实体查询的重复与超时问题

问题拆解

你的查询用UNION合并了两类孪生实体:

  • 标记为「孪生」类(wd:Q159979)的实体
  • 通过同生日+亲生母亲关联找到的有孪生兄弟姐妹的实体

但同时满足两类条件的实体会重复输出(比如丹麦约瑟芬公主),一条带具体孪生信息(?twin_2_name/?twin_2_desc),一条不带。你要的是优先保留有孪生信息的条目,只有当没有孪生信息时才显示缺失值,之前试了COALESCE没用还超时。

优化后的查询方案

核心逻辑是先抓取有明确孪生对象的条目,再补全那些找不到孪生对象但属于「孪生」类的实体,同时优化查询逻辑减少计算量:

SELECT ?twin_name ?twin_desc ?date_birth ?twin_2_name ?twin_2_desc
WHERE {
  # 第一部分:优先获取有明确孪生兄弟姐妹的实体
  {
    ?twin p:P569 ?p569 .
    ?p569 wikibase:rank wikibase:BestRank ;
          psv:P569 ?psv569 .
    ?psv569 wikibase:timePrecision ?time_precision ;
            wikibase:timeValue ?date_birth .
    FILTER (?time_precision >= 11)
    
    # 匹配亲生母亲的两种方式
    { ?twin wdt:P25 ?mother }
    UNION
    { ?twin ^wdt:P40 ?mother . ?mother wdt:P21 wd:Q6581072 }
    
    ?mother wdt:P40 ?twin_2 .
    FILTER (?twin != ?twin_2)
    ?twin_2 wdt:P569 ?date_birth .
    
    # 孪生对象的英文名称和描述
    ?twin_2 rdfs:label ?twin_2_name . FILTER (lang(?twin_2_name) = "en")
    ?twin_2 schema:description ?twin_2_desc . FILTER (lang(?twin_2_desc) = "en")
  }
  UNION
  # 第二部分:仅补充那些找不到孪生对象,但属于「孪生」类的实体
  {
    ?twin wdt:P31/(wdt:P279)* wd:Q159979 .
    ?twin wdt:P569 ?date_birth .
    
    # 排除已经在第一部分匹配到的实体,避免重复
    FILTER NOT EXISTS {
      ?twin p:P569 ?p569 .
      ?p569 wikibase:rank wikibase:BestRank ;
            psv:P569 ?psv569 .
      ?psv569 wikibase:timePrecision ?time_precision ;
              wikibase:timeValue ?date_birth .
      FILTER (?time_precision >= 11)
      
      { ?twin wdt:P25 ?mother }
      UNION
      { ?twin ^wdt:P40 ?mother . ?mother wdt:P21 wd:Q6581072 }
      
      ?mother wdt:P40 ?twin_2 .
      FILTER (?twin != ?twin_2)
      ?twin_2 wdt:P569 ?date_birth .
    }
    
    # 无孪生信息时显示占位符,不需要的话可以删掉这两行
    BIND("-" AS ?twin_2_name)
    BIND("-" AS ?twin_2_desc)
  }
  
  # 主实体的英文名称和描述
  ?twin rdfs:label ?twin_name . FILTER (lang(?twin_name) = "en")
  ?twin schema:description ?twin_desc . FILTER (lang(?twin_desc) = "en")
  
  # 按站点链接数排序(保留原逻辑,嫌慢可以删掉)
  ?twin ^schema:about/wikibase:sitelinks ?sitelinks .
}
ORDER BY DESC(?sitelinks)

关键改进点

  1. 去重逻辑:用FILTER NOT EXISTS确保第二部分只补充第一部分没覆盖到的实体,彻底避免重复
  2. 性能优化:
    • 删掉原查询的DISTINCT,减少不必要的去重计算
    • 修正了原查询中rdf:type wikibase:BestRank的错误,应该用wikibase:rank wikibase:BestRank来指定最佳排名的声明
    • 把重复的匹配逻辑放到FILTER NOT EXISTS里,避免重复遍历数据
  3. 需求匹配:完全实现你要的「有孪生信息就留,没有才显示缺失」的逻辑

额外提示

  • 如果不想显示-占位符,直接删掉那两行BIND,缺失字段会为空
  • 如果还是超时,建议去掉sitelinks相关的排序(这个字段需要统计每个实体的站点链接数,计算量很大),或者加LIMIT限制返回条数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:17:29