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.")
> > 
> > 
> 

Reply via email to