Datenbanken:Übung 8

Aus Tudwiki
Version vom 29. Juli 2007, 17:10 Uhr von 141.76.120.123 (Diskussion)

(Unterschied) Nächstältere Version→ | Aktuelle Version (Unterschied) | ←Nächstjüngere Version (Unterschied)
Wechseln zu: Navigation, Suche

Aufgabe 2[Bearbeiten]

Formulieren Sie eine XQuery-Anweisung, welche alle Bücher ermittelt, die (mindestens) einen Autor mit dem Nachname "Lehner" aufweisen.
<lehner-buecher>
{
	for $buch in doc("bib.xml")//book 
	where some $author in $buch/author satisfies ($author/lastname = "Lehner")

	return $buch/title
}
</lehner-buecher>


Aufgabe 3[Bearbeiten]

Für eine Preisübersicht sollen die Bücher nach dem Preis sortiert dargestellt werden. Geben Sie einen XQuery-Ausdruck an, der den Titel und den Preis der Bücher aufsteigend nach dem Preis sortiert ausgibt.
<buecher>
{
	for $buch in doc("bib.xml")//book 
	order by xs:decimal($buch/price) 

	return 
		<buch>
			{ $buch/title }
			{ $buch/price }
		</buch>
}
</buecher>
(a) Wie kann die Position von Bücher ohne Preis beeinflusst werden?
	order by xs:decimal($buch/price) empty least

oder

	order by xs:decimal($buch/price) empty greatest
(b) Was bewirkt die Angabe von stable bei der Sortierung?
	stable order by xs:decimal($buch/price)

Wenn es zwei Bücher gibt mit dem gleichen Preis, dann wird die Reihenfolge des Dokuments behalten.


Aufgabe 4[Bearbeiten]

Zur Unterstützung der Kaufentscheidung sollen die Bücher in teuere und billige Bücher eingeteilt werden. Teuere Bücher sind solche, deren Preis über dem durchschnittlichen Preis aller Bücher liegt, alle anderen Bücher sind billige Bücher. Formulieren Sie eine XQuery-Anweisung, die den Titel und den Preis sowie die Information, ob es sich um ein teures oder billiges Buch handelt, ausgibt.
<buecherliste>
{
	let $input := doc("bib.xml")
	let $schnitt := avg($input//book/price)

	for $buch in $input//book
	return 
		if (xs:decimal($buch/price) > $schnitt) 
			then <teuer titel="{$buch/title}" preis="{$buch/price}" />
			else <billig titel="{$buch/title}" preis="{$buch/price}" />
	
}
</buecherliste>

Alternative Lösung

  <bib>
  
  {
  let $schnitt:=fn:avg(doc("bib.xml")//price)
  for $x in doc("bib.xml")//book
  
  return
  
  if (xs:decimal($x/price)>$schnitt) then
   (
    <book typ="teuer">
     {$x/title}
     {$x/price}
    </book>
   )
  else  
   (
    <book typ="billig">
     {$x/title}
     {$x/price}
    </book>
   )
  }
  
  </bib>


Aufgabe 5[Bearbeiten]

Um den Absatz zu steigern, sollen Bücherpakete aus Büchern mit gemeinsamen Autoren angeboten werden. Geben Sie einen XQuery-Ausdruck an, der Bücherpaare, also eine Liste mit jeweils zwei Buchtiteln, die einen gemeinsamen Autor aufweisen, ausgibt.

<buecherpaare>
{
	let $books := doc("bib.xml")//book
	for $a in $books, $b in $books
	where $a/author = $b/author and $a/title < $b/title

	return
		<buchpaar>
			{$a/title}
			{$b/title}
		</buchpaar>
}
</buecherpaare>


Alternative Lösung

  <buecherpaare>
  {
  for $b1 in doc("bib.xml")//book
  for $b2 in doc("bib.xml")//book
     
     for $author in $b1/author
     for $author2 in $b2/author
  
     return
     
     if(($author=$author2) and ($b1/title<$b2/title))
     then
        (
        <paar>
          {$b1/title}
          {$b2/title}
          {$author}
        </paar>
        )
     else
        ()
  }
  </buecherpaare>

Aufgabe 6[Bearbeiten]

Formulieren Sie einen XQuery-Ausdruck, der alle Bücher ausgibt (Buchtitel und Anzahl Autoren), die von mehr als zwei Autoren geschrieben wurden.

<buecherliste>
{
	for $buch in doc("bib.xml")//book
	let $autoren := count($buch/author)
	where $autoren > 2
	return
		<buch>
			{$buch/title}
			<anzahl_autoren>{$autoren}</anzahl_autoren>
		</buch>
}
</buecherliste>


Aufgabe 7[Bearbeiten]

Zu einigen in bib.xml genannten Autoren sind in address.xml Angaben zum Wohnort hinterlegt. Gesucht sind zu jedem Buch der Autor und dessen Wohnort.
(a) Geben Sie eine entsprechende XQuery-Anweisung an, die auch Bücher ausgibt, für die es keine Adressinformationen über die Autoren gibt (Outer Join Semantik)
<buecherliste>
{
	let $bucher := doc("bib.xml")//book
	let $adressen := doc("address.xml")//address
	for $buch in $bucher
	return
		<buch>
			{$buch/title}
			{
				for $adresse in $adressen
				where $buch/author/firstname = $adresse/firstname and $buch/author/lastname = $adresse/lastname
				return
					<author name="{$adresse/lastname}" city="{$adresse/city}" />
			}
		</buch>
}
</buecherliste>
(b) Passen Sie diesen XQuery-Ausdruck so an, dass nur die Bücher erscheinen, für die zumindest teilweise Adressinformationen über die Autoren bekannt sind (Inner Join Semantik)
<buecherliste>
{
	let $bucher := doc("bib.xml")//book
	let $adressen := doc("address.xml")//address
	for $buch in $bucher
	for $adresse in $adressen
		where $buch/author/firstname = $adresse/firstname and $buch/author/lastname = $adresse/lastname

	return
		<buch>
			{$buch/title}
			<author name="{$adresse/lastname}" city="{$adresse/city}" />
		</buch>

}
</buecherliste>


Aufgabe 8[Bearbeiten]

Gegeben ist eine Übersicht aus Büchern und Zeitschriften (publications.xml).
(a) Geben Sie einen XQuery-Ausdruck an, der den durchschnittlichen Preis für die beiden Kategorien books und magazins ausgibt.
<bib>
{
	for $bib in doc("publications.xml")//bib/*
	let $preis := $bib/*/price
	return
		<preis kategorie="{fn:node-name($bib)}">
			{avg($preis)}
		</preis>
}
</bib>
(b) Formulieren Sie einen weiteren XQuery-Ausdruck, der die Autoren absteigend nach der Anzahl ihrer Bücher (nicht Zeitschriften) ausgibt.
<autorenliste>
{
	for $autor in fn:distinct-values(doc("publications.xml")//author)
	let $anzahl := count(doc("publications.xml")//book[author = $autor])
	order by $anzahl descending
	return
		<autor>
			<name>{$autor}</name>
			<anzahl_buecher>{$anzahl}</anzahl_buecher>
		</autor>
}
</autorenliste>