группа xquery, не удаляя повторяющиеся элементы

У меня есть XML-документ,

<resultsets>
    <row>
        <first_name>Georgi</first_name>
        <last_name>Facello</last_name>
    </row>
    <row>
        <first_name>Bezalel</first_name>
        <last_name>Simmel</last_name>
    </row>
    <row>
        <first_name>Bezalel</first_name>
        <last_name>Hass</last_name>
    </row>
</resultsets>

Я хочу отсортировать имена и удалить повторяющиеся имена, чтобы получить это:

<resultsets>
    <row>
        <first_name>Bezalel</first_name>
        <last_name>Simmel</last_name>
    </row>
    <row>
        <first_name>Georgi</first_name>
        <last_name>Facello</last_name>
    </row>
</resultsets>

Ниже приведен код, который я написал:

for $last_name at $count1 in doc("employees.xml")//last_name,
$first_name at $count2 in doc("employees.xml")//first_name
let $f := $first_name
where ( $count1=$count2 )
group by $f
order by $f
return 
<row> 
     {$f}
     {$last_name}
</row>

Однако этот код сортирует XML-документ по именам, но не может удалить повторяющееся имя ('Bezalel'), он возвращает:

   <resultsets>
        <row>
            <first_name>Bezalel</first_name>
            <last_name>Simmel</last_name>
        </row>
        <row>
            <first_name>Bezalel</first_name>
            <last_name>Hass</last_name>
        </row>
        <row>
            <first_name>Georgi</first_name>
            <last_name>Facello</last_name>
        </row>
    </resultsets>

Я знаю, как решить эту проблему с помощью двух операторов FLOWR. group by странное поведение, не могли бы вы объяснить, почему он не удаляет дубликаты? Есть ли способ решить эту проблему, используя ОДИН цикл FLOWR и ТОЛЬКО $first_name и $last_name две переменные? Спасибо,


person Judah Flynn    schedule 16.02.2018    source источник


Ответы (1)


Я бы просто сгруппировал row элементы по first_name дочерним элементам, а затем вывел бы первый элемент в каждой группе, чтобы гарантировать, что вы не получите дубликатов:

<resultssets>
{
    for $row in resultsets/row
    group by $fname := $row/first_name
    order by $fname
    return
        $row[1]    
}
</resultssets>

http://xqueryfiddle.liberty-development.net/jyyiVhf

О том, как работает предложение group by, см. https://www.w3.org/TR/xquery-31/#id-group-by, в котором говорится:

Предложение group by назначает каждый кортеж предварительной группировки группе и генерирует один кортеж после группировки для каждой группы. В кортеже после группировки для группы каждый ключ группировки представлен переменной, которая была указана в GroupingSpec, и каждая переменная, которая появляется в кортежах предварительной группировки, которые были назначены этой группе, представлена ​​переменной того же имя, привязанное к последовательности всех значений, связанных с переменной в любом из этих кортежей предварительной группировки.

person Martin Honnen    schedule 17.02.2018