在 Xquery 中有效地对存在于两个文档(内部连接)中的元素进行分组

Efficiently grouping elements that exists in both documents (inner join) in Xquery

我有以下数据:

<Subjects>
    <Subject>
        <Id>1</Id>
        <Name>Maths</Name>
    </Subject>
    <Subject>
        <Id>2</Id>
        <Name>Science</Name>
    </Subject>
    <Subject>
        <Id>2</Id>
        <Name>Advanced Science</Name>
    </Subject>
</Subjects>

和:

<Courses>
    <Course>
        <SubjectId>1</SubjectId>
        <Name>Algebra I</Name>
    </Course>
    <Course>
        <SubjectId>1</SubjectId>
        <Name>Algebra II</Name>
    </Course>
    <Course>
        <SubjectId>1</SubjectId>
        <Name>Percentages</Name>
    </Course>
    <Course>
        <SubjectId>2</SubjectId>
        <Name>Physics</Name>
    </Course>
    <Course>
        <SubjectId>2</SubjectId>
        <Name>Biology</Name>
    </Course>
</Courses>

我希望从共享相同 ID 的两个文档中有效地获取元素。

我想得到这样的结果:

<Results>
    <Result>
        <Table1>
            <Subject>
                <Id>1</Id>
                <Name>Maths</Name>
            </Subject>
        </Table1>
        <Table2>
            <Course>
                <SubjectId>1</SubjectId>
                <Name>Algebra I</Name>
            </Course>
            <Course>
                <SubjectId>1</SubjectId>
                <Name>Algebra II</Name>
            </Course>
            <Course>
                <SubjectId>1</SubjectId>
                <Name>Percentages</Name>
            </Course>
        </Table2>
    </Result>
    <Result>
        <Table1>
            <Subject>
                <Id>2</Id>
                <Name>Science</Name>
            </Subject>
            <Subject>
                <Id>2</Id>
                <Name>Advanced Science</Name>
            </Subject>
        </Table1>
        <Table2>
            <Course>
                <SubjectId>2</SubjectId>
                <Name>Physics</Name>
            </Course>
            <Course>
                <SubjectId>2</SubjectId>
                <Name>Biology</Name>
            </Course>
        </Table2>
    </Result>
</Results>

到目前为止我有两个解决方案:

<Results>       
{
   for $e2 in $t2/Course
   let $foriegnId := $e2/SubjectId
   group by $foriegnId
   let $e1 := $t1/Subject[Id = $foriegnId]
   where $e1
   return
      <Result>
         <Table1>
            {$e1}
         </Table1>
         <Table2>
            {$e2}
         </Table2>
      </Result>
}
</Results>

反之:

<Results>       
{
   for $e1 in $t1/Subject
   let $id := $e1/Id
   group by $id
   let $e2 := $t2/Course[SubjectId = $id]
   where $e2
   return
      <Result>
         <Table1>
            {$e1}
         </Table1>
         <Table2>
            {$e2}
         </Table2>
      </Result>
}
</Results>

有没有更有效的方法? 也许利用多个组?

更新 目前我的代码的一个主要问题是它的性能高度依赖于哪个 table 更大。例如,在第二个 table 更大的情况下,第一个解决方案更好,反之亦然。

我觉得你的解决方案很合理。它在像 Saxon-EE 这样进行连接优化的处理器上比在不进行连接优化的处理器(如 Saxon-HE)上的性能要好得多。如果你想手动优化它,最简单的方法是切换到使用 XSLT:使用 key() 函数替换过滤器表达式 $t1/Subject[Id = $foriegnId],在没有优化的情况下,搜索你的第二个文件一次对于第一个文件中选择的每个元素。