Order-by-Klausel
Die Reihenfolge, in der die return-Klausel eines FLWOR-Ausdrucks mit den entsprechenden Variablenbelegungen ausgewertet wird, kann durch die Sortierungsklausel order by explizit erzwungen werden. Die relative Ordnung von zwei Zuständen von Variablenbelegungen wird dabei durch die Ordnungsanweisung festgelegt. Zum Beispiel erzwingt die order by-Klausel in der folgenden Anweisung die Ordnung, wie sie implizit bei einer Vertauschung der for-Klauseln gegeben wäre:
for $y at $j in(<Labor/>, <Station/>)
for $x at $i in(<Arzt/>, <Pfleger/>)
order by $i, $j
return
<Zuordnung>
<Beruf>{ $i }</Beruf><Ort>{ $j }</Ort>
</Zuordnung>
Falls es sich um Zeichenketten handelt, kann zusätzlich eine Sortierordnung ("collation") angegeben werden. Details zur Sortierung auf Zeichenketten finden sich bei der Beschreibung der XQuery-Zeichenkettenfunktionen. In folgendem Beispiel werden die Medikamente hinsichtlich US-amerikanischer Sortierungsfolge, basierend auf der Bezeichnung des Medikamentes, ausgegeben; gleiche Medikamente werden absteigend nach ihrem Preis sortiert:
for $i in fn:doc("Verbrauchsartikel.xml")//Artikel
order by $i/Bezeichnung
collation "http://www.xquery-buch.de/eng-us",
$i/Einzelpreis descending
return $i
Die stable order by-Variante der normalen order by-Klausel zeigt dann Wirkung, wenn zwei Einträge bzgl. des vorgegebenen Sortierungskriteriums nicht eindeutig unterschieden werden können. Während bei der stable-Variante die Einhaltung der Reihenfolge der Elemente bezüglich des Ausgangsdokumentes erzwungen wird, ist die Reihenfolge in der normalen Variante der order by-Klausel in diesem Fall implementierungsabhängig. In folgendem Beispiel wird die Reihenfolge der Mitarbeiter aus dem Originaldokument übernommen, wenn sie an dem gleichen Tag Geburtstag haben:
for $p in fn:doc("Hochwaldklinik.xml")//Personal
stable order by fn:get-month-from-date($p//Geburtsdatum),
fn:get-day-from-date($p//Geburtsdatum)
return $p
Mit Bezug auf die Ausführungsreihenfolge von for-Anweisungen liefert folgender FLWOR-Ausdruck das gleiche Ergebnis wie die obige Anweisung mit dem Sortierkriterium nach $i, $j:
for $y at $j in (<Labor/>, <Station/>)
for $x at $i in (<Arzt/>, <Pfleger/>)
stable order by $i
return
<Zuordnung>
<Beruf>{ $i }</Beruf><Ort>{ $j }</Ort>
</Zuordnung>
Neben der aufsteigenden bzw. absteigenden Sortierung kann als weiterer Sortierungsmodifikator empty greatest bzw. empty least angegeben werden, wobei die Sortierungssemantik insbesondere bei leeren Sequenzen und NaN-Werten eindeutig geregelt wird. Ist der empty_least-Modifikator angegeben, so wird xi vor xj einsortiert, falls xi eine leere und xj eine nichtleere Sequenz repräsentiert bzw. falls xi den Wert NaN repräsentiert und xj weder NaN noch eine leere Sequenz ist.
Im Fall von Zeichenketten ergibt sich das gleiche Ergebnis, wenn die Zeichenkettenfunktion fn:compare(xi, xj, c) bei expliziter Sortierreihenfolge, definiert durch die Sortierordnung c, einen Wert größer als 0 liefert bzw. falls der normale Vergleich xi < xj zu true evaluiert. Gegensätzliches gilt, falls der inverse Modifikator empty greatest angegeben ist. Fehlt die explizite Angabe eines derartigen Modifikators, so entscheidet die Implementierung, welche der beiden Regeln im Konfliktfall Anwendung findet. Das folgende Beispiel sortiert Medikamente nach ihrem Preis, wobei fehlende Preisangaben semantisch als der kleinstmögliche Preis interpretiert werden und (bedingt durch die absteigende Sortierung) am Ende in der Medikamentenliste erscheinen.
for $i in fn:doc ("Verbrauchsartikel.xml")//Artikel
order by $i/Einzelpreis descending empty least
return $i
Quelle: "XQuery – Grundlagen und fortgeschrittene Methoden", dpunkt-Verlag, Heidelberg (2004)
<< zurück | vor >> |