• +49-(0)721-402485-12
Ihre Experten für XML, XQuery und XML-Datenbanken

Gruppierung über mehrere Attribute

Sind Fakten nach unterschiedlichen Kriterien auszuweisen, so ist eine Gruppierung über mehrere Attribute notwendig. Analog zur relationalen bzw. SQL-basierten Darstellung durch Vergrößerung der Menge der Gruppierungsattribute in der GROUP BY- bzw. SELECT-Klausel kann in XQuery eine Gruppierung über mehrere Attribute erreicht werden, indem mehrere for-Klauseln zur Gruppenbildung definiert werden. Wird beispielsweise davon ausgegangen, dass die Mitarbeiterliste des laufenden Beispiels zusätzlich für jeden Mitarbeiter einen Eintrag zur Abbildung des Geschlechts hat, so kann das durchschnittliche Alter pro Berufsgruppe und pro Geschlecht ermittelt werden.

<MedizinischesPersonal>
<Ärzte>
<Arzt><Name>Naumann</Name>
 <Alter>32</Alter>
 <Geschlecht>m</Geschlecht> </Arzt>
<Arzt><Name>Shore</Name>
 <Alter>27</Alter>
 <Geschlecht>w</Geschlecht> </Arzt>
<Arzt><Name>Meier</Name>
 <Alter>25</Alter>
 <Geschlecht>m</Geschlecht> </Arzt>
</Ärzte>
<Pflegepersonal>
<Pfleger><Name>Guldenstern</Name>
 <Alter>41</Alter>
 <Geschlecht>w</Geschlecht> </Pfleger>
<Pfleger><Name>Murawitz</Name>
 <Alter>65</Alter>
 <Geschlecht>w</Geschlecht> </Pfleger>
</Pflegepersonal>
</MedizinischesPersonal>

Der entsprechende FLWOR-Ausdruck würde sich wie folgt ergeben:

<MedizinischesPersonal>
{
for $b in fn:distinct-values(
for $i in fn:doc("...")//MedizinischesPersonal/*/*
return fn:name($i)),
$g in fn:distinct-values(fn:doc("...")//Geschlecht)
let $x := fn:doc("...")//
[fn:name(.) = $b and Geschlecht=$g]/Alter
return
(<Berufsgruppe>{ $b }</Berufsgruppe>,
<Geschlecht>{ $g }</Geschlecht>,
<Alter>{ fn:avg($x) }</Alter>)
}
</MedizinischesPersonal>

Jedes weitere Gruppierungskriterium wird in einem FLWOR-Ausdruck somit durch eine neue Iterationsvariable gekennzeichnet. Die Semantik der "geschachtelten Schleifen" bei einer Gruppierung über mehrere Attribute impliziert darüber hinaus, dass grundsätzlich alle möglichen Kombinationen erzeugt werden, unabhängig davon, ob für die entsprechende Kombination im Ausgangsdatenbestand mindestens ein Eintrag existiert. Um die "klassische" Gruppierungssemantik zu simulieren und nur die Kombinationen auszugeben, die mindestens einen zu aggregierenden Eintrag aufweisen, ist die Funktion fn:exists() in der where-Klausel einzusetzen, mit deren Hilfe die Existenz eines Eintrags in der zu aggregierenden Sequenz zu testen ist. Die obige Anweisung verändert sich somit zu folgendem Ausdruck:

<MedizinischesPersonal>
{
for $b in fn:distinct-values(
for $i in fn:doc("...")//MedizinischesPersonal/*/*
return fn:name($i)),
$g in fn:distinct-values(fn:doc("...")//Geschlecht)
let $x := fn:doc("...")//
[fn:name(.) = $b and Geschlecht=$g]/Alter
where fn:exists($x)
return
(<Berufsgruppe>{ $b }<Berufsgruppe>,
<Geschlecht>{ $g }</Geschlecht>,
<Alter>{ fn:avg($x) }</Alter>)
}
</MedizinischesPersonal>

 

Quelle: "XQuery – Grundlagen und fortgeschrittene Methoden", dpunkt-Verlag, Heidelberg (2004)

<< zurückvor >>