如何在OrientDB中不使用UNIONALL拼接多个查询结果集
我来给你梳理几个在OrientDB里不用UNIONALL拼接多查询结果的实用方法,结合你提到的Student和Company节点关系来举例说明:
方法1:用LET子句聚合结果集
OrientDB的LET关键字可以帮我们把多个查询的结果先存在变量里,最后一次性提取合并,完全替代UNIONALL的作用。比如你想同时获取Student的关联信息和Company的关联信息,可以这么写:
LET $students = (SELECT s.*, out('HasLocation').name AS location, out('HasInterest').name AS interest, out('LookingFor').name AS jobType FROM Student s), $companies = (SELECT c.*, out('HasLocation').name AS location, out('HasInterest').name AS interest, out('HasType').name AS jobType FROM Company c) SELECT * FROM [$students, $companies]
这里把Student和Company的查询结果分别存在$students和$companies变量里,最后通过[$students, $companies]把两个结果数组合并输出。建议尽量让两个子查询的字段保持一致,这样结果集的结构会更规整,避免出现大量null值。
方法2:通过图遍历一次性整合关联数据
如果你的需求是找到匹配的Student和Company(比如两者的Location、Interest、岗位类型都对应),那完全不用拆分多个查询再拼接,直接用OrientDB的图遍历能力就能搞定。比如要找申请实习岗位的学生和提供实习的公司匹配结果:
SELECT s.name AS studentName, c.name AS companyName, loc.name AS location, int.name AS interest, t.name AS jobType FROM Student s MATCH { class: Student, as: s, where: (out('LookingFor').name = '实习') }.out('HasLocation'){as: loc} .in('HasLocation'){class: Company, as: c} .out('HasInterest'){as: int, where: (int IN s.out('HasInterest'))} .in('HasType'){as: t, where: (t.name = s.out('LookingFor').name)} RETURN studentName, companyName, location, interest, jobType
这个查询通过MATCH语句顺着边的关系遍历,直接把符合条件的Student和Company关联起来,一次性输出整合后的匹配结果,比拆分查询再拼接高效得多。
方法3:嵌套查询作为数据源直接合并
如果只是简单的拼接不同查询的结果,也可以直接在FROM子句里嵌套多个查询,用数组包裹起来就行,写法更简洁:
SELECT * FROM [ (SELECT s.name, 'student' AS entityType FROM Student s), (SELECT c.name, 'company' AS entityType FROM Company c) ]
这个写法和UNIONALL的效果完全一致,而且不需要额外定义变量,适合快速拼接简单的结果集。
小提醒
- 如果合并后的结果有重复数据,可以在主查询里加上
DISTINCT关键字来去重,比如SELECT DISTINCT * FROM [$students, $companies]; - 当字段不一致时,结果集中缺少的字段会用
null填充,所以尽量让子查询的字段对齐,方便后续处理。
内容的提问来源于stack exchange,提问作者Harsh Butani
相关产品推荐
相关产品推荐

