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

Aggregationsfunktionen

Die Aggregation ist in XQuery angelehnt an die Formulierung in OQL, wobei die "klassischen" Aggregationsfunktionen fn:sum(), fn:avg(), fn:count(), fn:min() und fn:max() zur Verfügung stehen, die als Argument eine Sequenz erwarten und folgende Spezifika realisieren:

Berechnung der Kardinalität (fn:count())

Die Funktion fn:count() liefert die Anzahl der Elemente innerhalb der als Parameter übergebenen Sequenz. Eine leere Sequenz resultiert in einem Rückgabewert 0.

Berechnung des Durchschnittswertes (fn:avg())

Die in der XQuery-Funktionsbibliothek definierte Funktion fn:avg() liefert eine leere Sequenz, falls eine leere Sequenz als Argument übergeben wird; ist mindestens ein Element der übergebenen Sequenz vom Datentyp xs:float oder xs:double und weist es einen NaN-Wert auf, so wird ein NaN-Wert als Ergebnis zurückgeliefert. Im Allgemeinen müssen alle Elemente den gleichen Datentyp haben. Ist dies nicht der Fall, so erfolgt eine Anpassung untereinander, was insbesondere für Elemente vom Datentyp xs:untypedAtomic zutrifft.

Sind alle Elemente vom Datentyp xs:untypedAtomic, so werden sie in einen Wert vom Datentyp xs:double implizit konvertiert. Zeitangaben müssen grundsätzlich vom Datentyp xsd:yearMonthDuration oder xsd:dayTimeDuration sein. Folgende Beispiele illustrieren die Semantik der Berechnung eines Durchschnittswertes:

fn:avg((3,4,5))

liefert offensichtlich den Wert 4 mit Datentyp xs:decimal.

fn:avg((xdt:yearMonthDuration("P20Y"),
xdt:yearMonthDuration("P10M") ))

liefert einen Wert von 125 Monaten vom Datentyp xsd:yearMonthduration.

Bestimmung minimaler und maximaler Werte (fn:min() und fn:max())

Die beiden Funktionen liefern jeweils das wertemäßig kleinste bzw. größte Element aus der übergebenen Sequenz zurück. Bei einem Patt ist die Auswahl implementierungsabhängig. Wie bei der Durchschnittsberechnung ist im allgemeinen Fall gefordert, dass alle Elemente vom gleichen Typ sind; Werte vom Datentyp xdt:untypedAtomic werden dabei in Werte vom Datentyp xs:double konvertiert; die Regeln für NaN-wertige Elemente gelten ebenso analog.

Mit Bezug auf Zeitangaben ist eine Bestimmung des größten bzw. kleinsten Wertes auch für Werte vom Datentyp xs:dateTime, xs:date und xs:time zugelassen. Die beiden Funktionen sind dabei durch folgenden FLWOR-Ausdruck beispielsweise als benutzerdefinierte Funktion zu simulieren. So kann fn:max($x) durch folgenden Ausdruck substituiert werden:

let $y := for $e in $x
order by $e (: optional: collation bei Zeichenketten :)
return $e
return $y[fn:last()]

Eine Modifikation der return-Klausel zu

return $y[1]

resultiert dann in einer Bestimmung des minimalen Wertes. Folgende Beispiele illustrieren zusätzlich die Möglichkeit von XQuery zur Aggregation bezüglich Minimum und Maximum:

fn:max((3,4,5))

liefert offensichtlich den Wert 5 vom Datentyp xs:integer.

fn:max((3,4,"Zero"))

resultiert in einer Fehlermeldung, da die Datentypen unterschiedlich sind. Der Ausdruck

fn:max(("a", "b", "c"))

hingegen liefert "c" zurück, wobei das Ergebnis durch Angabe einer spezifischen Sortierordnung modifiziert werden kann.

Summation (fn:sum())

Die Summation erfordert wiederum, dass alle Elemente vom gleichen Typ sind; Elemente vom Typ xdt:untypedAtomic werden in Werte vom Datentyp xs:double konvertiert. Eine leere Sequenz als Parameter resultiert in der Rückgabe des Wertes 0.0E0 vom Typ xs:double. Die Summation von Zeitangaben bezieht sich ausschließlich auf Zeitintervalle, zum Beispiel:

fn:sum((xdt:yearMonthDuration("P20Y"),
xdt:yearMonthDuration("P10M")))

ergibt ein Zeitintervall von 250 Monaten als Ausprägung von xsd:yearMonthDuration. Die numerische Summation funktioniert wie erwartet:

fn:sum((4,5,6))

liefert 15.

fn:sum((1,(2 to 9)[.<5], 10))

liefert 20.

Der erste Ausdruck liefert offensichtlich den Wert 15. Der zweite Ausdruck zeigt, dass jeder Ausdruck, der eine Sequenz zurückliefert, auch als Parameter beim Funktionsaufruf erlaubt ist. Das Ergebnis hat dabei den Wert 1+2+3+4+10=20.

SignaturBeschreibung
fn:count(
$arg as item()*)
as xs:integer
liefert die Anzahl der Elemente der übergebenen Sequenz zurück
fn:avg(
$arg as xdt:anyAtomicType*)
as xdt:anyAtomicType?
liefert den durchschnittlichen Wert aller Elemente der übergebenen Sequenz:
sum($arg) div count($arg)
fn:max(
$arg as xdt:anyAtomicType*[,
$collation as string])
as xdt:anyAtomicType?
liefert den wertemäßig größten Wert optional bezüglich einer Sortierordnung zurück
fn:min(
$arg as xdt:anyAtomicType*[,
$collation as string])
as xdt:anyAtomicType?
liefert den wertemäßig kleinsten Wert optional bezüglich einer Sortierordnung zurück
fn:sum(
$arg as xdt:anyAtomicType*[,
$zero as xdt:anyAtomicType?])
as xdt:anyAtomicType?
liefert den summarischen Wert aller in der
Sequenz enthaltenen Elementwerte zurück;
wird der zweite Parameter nicht angegeben,
so wird der Wert 0.0E0 bei einer leeren Sequenz
zurückgeliefert; andernfalls der Wert des zweiten Parameters

Tab. Aggregationsfunktionen

Anzumerken ist an dieser Stelle, dass Aggregationsfunktionen eine Sequenz als Parameter erwarten. Der Ausdruck fn:sum(4,5,6) würde beispielsweise einen Fehler produzieren, da nicht eine Sequenz als ein Parameter, sondern drei Werte als je ein Parameter als Argumente interpretiert werden würden.

 

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

<< zurückvor >>