Hans-Juergen, thanks for this insight, that sheds even more light for me into the grouping with xquery...
> On 20 Dec 2022, at 08:42, Hans-Juergen Rennau <hren...@yahoo.de> wrote: > > Thank you for your kind words, Gerrit! Until a few weeks ago, my use of > grouping was a groping one also in my case - until I learned from the spec > that the FLWOR mechanics are only fully understood if we regard the clauses > as a pipeline of stations, each one transforming an input tuple stream into > an output tuple stream - that's the key. And that's at first weird, as we are > used to think in terms of "assignments", "loops", sorting, grouping, > filtering, counting devices. But when thinking of the different clauses as > just variants of a single idea - "tuple stream transformer" - everything is > decomposed into tiny bits - the details of how a particular kind of clause > maps its input tuples to output tuples. No interaction whatsoever between the > clauses, apart from output tuple streams becoming input tuple streams. > Suddenly it is not amazing any more that you can have any number of any kind > of clauses, e.g. several where clauses, and that the clauses can occur at any > position within the expression (except for the constraint that the first > clause must be let or for). And so, for example, I had always kept my fingers > crossed when adding an order by after a group by. Now I understand that once > the group by has done its thing and produced an output tuple stream according > to its rules, you have a tuple stream without any memory of what has happened > at earlier clauses. > > Am Montag, 19. Dezember 2022 um 23:48:45 MEZ hat Imsieke, Gerrit, le-tex > <gerrit.imsi...@le-tex.de> Folgendes geschrieben: > > > Thank you, Hans-Jürgen, for shedding really insightful light (if there > is such a thing) on this aspect of XQuery grouping, which I use > gropingly (pun intended) without fully understanding it. > > On 19.12.2022 23:19, Hans-Juergen Rennau wrote: > > I think the reason is a different one - it is related to the precise > > semantics of the group by clause. > > > > The group by clause maps each group of input tuples with equal grouping > > key(s) to a single output tuple, in which > > - the grouping variable(s) is/are bound to the key values (as you would > > expect) > > - all other variables are bound to the concatenated sequence of values > > bound to the variable name in the members of the group (which may cause > > surprises) > > > > So when a group has, say, 3 members, the variable $organisations is not > > any more bound to a single function item, but to a sequence of 3 > > function items (which are identical). Of course, a sequence of more than > > one function item cannot be called - only a single function item can be > > called. In order to check that this is the correct interpretation of the > > issue, you can remove the second assignment to $organisations, and > > append to the invocation the predicate [1] - then it works, as then you > > have again a single function item: > > > > <country>{$country/@name, $organizations[1]($country)}</country> > > > > One way to handle this in a more straightforward way is to shift the > > function item into an additional, outer FLWOR level at the beginning. > > While we are at it, let's shift both function items: > > > > let $organizations := function($country){ > > $doc//organization[members/@country = $country/@id]/@abbrev/string(.)} > > let $membershipPotentcy := function($orgs){ > > if (count($orgs)le 0) then 'none' else if (count($orgs) le 5) then > > 'few' else 'many'} > > return > > element Memberships { > > for $countries in $doc//country > > group by $mp:= $membershipPotentcy($organizations($countries)) > > order by $mp > > return > > element {$mp} { > > for $country in $countries > > return > > <country>{$country/@name, $organizations($country)}</country> > > }} > > > > > > Am Montag, 19. Dezember 2022 um 22:58:30 MEZ hat Graydon > > <graydon...@gmail.com <mailto:graydon...@gmail.com>> Folgendes geschrieben: > > > > > > On Mon, Dec 19, 2022 at 10:43:25PM +0100, Leo Studer scripsit: > > > > > In the code below I encounter the problem, that I have to define the > > same xPath function variable $organizations twice and I do not > > understand why. > > > > > > In line 10, you've used a let clause to bind a variable of type function > > to the name organizations. That's in context a specific FLOWR expression. > > > > The expression in the return clause of that FLOWR expression returns an > > element constructor where the contents expression contains another FLOWR > > expression. The first definition on line 10 will be out of scope in > > there. > > > > You could define the function with scope for the module: > > > > declare function local:getOrganizations($in as element(country)) > > as xs:string* { > > let $thisCountry as xs:string := $in/@id/string(); > > return $doc//organization[members/@country = > > $thisCountry]/@abbrev/string(.) > > }; > > > > And then use it in both places with the single definition. > > > > > > -- > > Graydon Saunders | graydon...@gmail.com <mailto:graydon...@gmail.com> > > <mailto:graydon...@gmail.com <mailto:graydon...@gmail.com>> > > Þæs oferéode, ðisses swá mæg. > > -- Deor ("That passed, so may this.") > > > > >