Aufgabe 3 - SQL-Abfragen · Abitur NRW Informatik GK · Haupttermin 2023
Thema: SQL-Abfragen · Aus der Prüfung GK · Haupttermin (2023)
Aufgabenstellung
Aufgabenstellung: Sachkontext Bahnlinien-Datenbank
Ein Informatikprojektkurs plant, einige Bahnlinien in einer Datenbank zu modellieren. In einer ersten Version sollen unter anderem die Bahnhöfe und die Streckenabschnitte erfasst werden.
Ein Streckenabschnitt ist eine direkte Verbindung von dem einen Bahnhof zu dem anderen Bahnhof ohne Zwischenhalt. Aus Sicherheitsgründen kann ein Streckenabschnitt nur in einer Richtung und somit nicht für die Gegenrichtung genutzt werden.
Eine Bahnlinie besteht aus Streckenabschnitten, die die Folge der Bahnhöfe auf dieser Bahnlinie beschreiben. Dabei wird für jeden zugehörigen Streckenabschnitt die Fahrzeit in Minuten angegeben.
Um die Daten zu verwalten, will der Projektkurs eine relationale Datenbank einrichten, die auf der folgenden Teilmodellierung beruht:
Die folgenden Aufgaben beziehen sich auf das in Abbildung 3 dargestellte Datenbankschema, das nur einen Teil der Gesamtdatenbank abbildet. Im Anhang stehen Beispieldaten zu diesem Schema zur Verfügung.
Anlage: Ausschnitt aus den Beispieldaten zum Datenbankschema
Bahnhof
Name
barrierefrei
Glücksdorf · 1
Oberdorf · 0
Medeburg · 1
Zweierwalde · 1
Hintertupfingen · 1
Bahnlinie
ID
Name
L1 · Bergexpress
L2 · Burglinie
L3 · Hintertupfingenlinie
L4 · Glücksdorfexpress
Streckenabschnitt
ID
vonBahnhofName
zuBahnhofname
1 · Glücksdorf · Oberdorf
2 · Oberdorf · Medeburg
3 · Medeburg · Hintertupfingen
4 · Medeburg · Zweierwalde
5 · Zweierwalde · Hintertupfingen
6 · Hintertupfingen · Glücksdorf
gehoertZu
StreckenabschnittID
BahnlinieID
Abschnittsnummer
Fahrzeit
1 · L1 · 1 · 30
2 · L1 · 2 · 20
3 · L1 · 3 · 90
1 · L2 · 1 · 40
2 · L2 · 2 · 50
4 · L2 · 3 · 30
5 · L3 · 1 · 50
6 · L4 · 1 · 90
Anhang: Dokumentationen der verwendeten Klassen
Die Klasse Bahnlinientest
Ein Objekt der Klasse wird genutzt, um die Datenbankverbindung und die Datenbankabfragen zu testen.
Bahnlinientest()
Ein Objekt vom Typ DatabaseConnector wird initialisiert und stellt die Datenbankverbindung her.
int ermittleEtwas(String pID)
Diese Methode ist Bestandteil der Teilaufgabe d.
Die Klasse DatabaseConnector
Ein Objekt der Klasse DatabaseConnector ermöglicht die Abfrage und Manipulation einer MySQL-Datenbank. Beim Erzeugen des Objekts wird eine Datenbankverbindung aufgebaut, sodass anschließend SQL-Anweisungen an diese Datenbank gerichtet werden können.
DatabaseConnector(String pIP, String pPort, String pDatabase, String pUsername, String pPassword)
Ein Objekt vom Typ DatabaseConnector wird erstellt, und eine Verbindung zur Datenbank wird aufgebaut. Mit den Parametern pIP und pPort werden die IP-Adresse und die Port-Nummer übergeben, unter denen die Datenbank mit Namen pDatabase zu erreichen ist. Mit den Parametern pUsername und pPassword werden Benutzername und Passwort für die Datenbank übergeben.
void executeStatement(String pSQLStatement)
Der Auftrag schickt den im Parameter pSQLStatement enthaltenen SQL-Befehl an die Datenbank ab. Handelt es sich bei pSQLStatement um einen SQL-Befehl, der eine Ergebnismenge liefert, so kann dieses Ergebnis anschließend mit der Methode getCurrentQueryResult abgerufen werden.
QueryResult getCurrentQueryResult()
Die Anfrage liefert das Ergebnis des letzten mit der Methode executeStatement an die Datenbank geschickten SQL-Befehls als Objekt vom Typ QueryResult zurück. Wurde bisher kein SQL-Befehl abgeschickt oder ergab der letzte Aufruf von executeStatement keine Ergebnismenge (z. B. bei einem INSERT-Befehl oder einem Syntaxfehler), so wird null geliefert.
String getErrorMessage()
Die Anfrage liefert null oder eine Fehlermeldung, die sich jeweils auf die letzte zuvor ausgeführte Datenbankoperation bezieht.
void close()
Die Datenbankverbindung wird geschlossen.
Die Klasse QueryResult
Ein Objekt der Klasse QueryResult stellt die Ergebnistabelle einer Datenbankanfrage mit Hilfe der Klasse DatabaseConnector dar. Objekte dieser Klasse werden nur von der Klasse DatabaseConnector erstellt. Die Klasse verfügt über keinen öffentlichen Konstruktor.
String[][] getData()
Die Anfrage liefert die Einträge der Ergebnistabelle als zweidimensionales Feld vom Typ String. Der erste Index des Feldes stellt die Zeile und der zweite die Spalte dar (d. h. String[zeile][spalte]).
String[] getColumnNames()
Die Anfrage liefert die Bezeichner der Spalten der Ergebnistabelle als Feld vom Typ String zurück.
String[] getColumnTypes()
Die Anfrage liefert die Typenbezeichnung der Spalten der Ergebnistabelle als Feld vom Typ String zurück. Die Bezeichnungen entsprechen den Angaben in der MySQL-Datenbank.
int getRowCount()
Die Anfrage liefert die Anzahl der Zeilen der Ergebnistabelle als int.
int getColumnCount()
Die Anfrage liefert die Anzahl der Spalten der Ergebnistabelle als int.
Teilaufgabe b)
Aus der Datenbank sollen die folgenden Angaben ermittelt werden:
i.
Ermittelt werden sollen die Namen der Bahnhöfe, die von Medeburg aus über einen einzelnen Streckenabschnitt unmittelbar erreicht werden können. Die Ausgabe soll aufsteigend nach Bahnhofsnamen geordnet sein. [3 Punkte]
ii.
Ermittelt werden sollen zu jeder Bahnlinie ihr Name und ihre gesamte Fahrzeit. [5 Punkte]
Teilaufgabe c)
Gegeben ist die nachstehende SQL-Anweisung:
1 SELECT gehoertZu.BahnlinieID, vonBahnhofName,
2 zuBahnhofname, Fahrzeit
3 FROM Streckenabschnitt
4 INNER JOIN gehoertZu
5 ON gehoertZu.StreckenabschnittID = Streckenabschnitt.ID
6 WHERE Fahrzeit = (
7 SELECT MAX(Fahrzeit)
8 FROM gehoertZu
9)
Analysieren und erläutern Sie die Unterabfrage in den Zeilen 7 – 8. [3 Punkte]
Analysieren und erläutern Sie die vollständige SQL-Anweisung. [4 Punkte]
Erläutern Sie bezogen auf den Sachzusammenhang, welche Information die vollständige SQL-Anweisung liefert. [3 Punkte]
Teilaufgabe d)
Eine Schülerin des Projektkurses hat zusätzlich eine Erweiterung programmiert. Abbildung 4 stellt einen Ausschnitt des Implementationsdiagramms dar.
Die nachstehende Methode der Klasse Bahnlinientest besitzt keine Dokumentation.
1 public int ermittleEtwas(String pID) {
2 boolean gefunden = false;
3 int anzahl = 1;
4 db.executeStatement("SELECT * FROM gehoertZu ");
5 if (db.getErrorMessage() == null) {
6 QueryResult qr = db.getCurrentQueryResult();
7 if (qr.getRowCount() > 0) {
8 for (int i = 0; i < qr.getRowCount(); i++) {
9 String bahnlinieID = qr.getData()[i][1];
10 if (pID.equals(bahnlinieID)) {
11 anzahl = anzahl + 1;
12 gefunden = true;
13 }
14 }
15 }
16 }
17 if (!gefunden) {
18 anzahl = -1;
19 }
20 return anzahl;
21 }
Analysieren Sie die Methode und erläutern Sie, wie sie arbeitet, wobei Sie die SQL-Anweisung in Zeile 4 einbeziehen. [4 Punkte]
Geben Sie jeweils den Rückgabewert der Methode an, wenn diese mit den Beispieldaten im Anhang aufgerufen wird: [4 Punkte]
:
:
:
Erläutern Sie bezogen auf den Sachkontext, welche Information die Methode bestimmt. [3 Punkte]
Entscheiden Sie, ob sich die von der Methode gelieferte Information auch mit einer SQL-Anweisung bestimmen lässt, sodass keine Schleife nötig ist. Begründen Sie kurz bzw. geben Sie die Idee oder die Anweisung an. [3 Punkte]

Lösung
Nach den offiziellen Korrekturhinweisen
b) i. Entwerfen Sie eine SQL-Anweisung: Ermittelt werden sollen die Namen der Bahnhöfe, die von Medeburg aus über einen einzelnen Streckenabschnitt unmittelbar erreicht werden können. Die Ausgabe soll aufsteigend nach Bahnhofsnamen geordnet sein.
Lösung: ```sql SELECT zuBahnhofname FROM Streckenabschnitt WHERE vonBahnhofName = 'Medeburg' ORDER BY zuBahnhofname ASC ```
b) ii. Entwerfen Sie eine SQL-Anweisung: Ermittelt werden sollen zu jeder Bahnlinie ihr Name und ihre gesamte Fahrzeit.
Lösung: ```sql SELECT Bahnlinie.Name, SUM(gehoertZu.Fahrzeit) FROM Bahnlinie INNER JOIN gehoertZu ON Bahnlinie.ID = gehoertZu.BahnlinieID GROUP BY Bahnlinie.ID ```
c) Analysieren und erläutern Sie die Unterabfrage in den Zeilen 7 – 8.
Lösung: In der Unterabfrage wird der größte Wert für das Attribut Fahrzeit aus der Tabelle gehoertZu ermittelt.
c) Analysieren und erläutern Sie die vollständige SQL-Anweisung.
Lösung: In den Zeilen 1–2 findet die Projektion auf die Attribute gehoertZu.BahnlinieID, vonBahnhofName, zuBahnhofname und Fahrzeit statt. In den Zeilen 3–5 werden Streckenabschnitt und gehoertZu über einen Inner Join verknüpft. In Zeile 6 werden die Datensätze ausgewählt, deren Fahrzeit dem Maximalwert aus der Unterabfrage entspricht.
c) Erläutern Sie bezogen auf den Sachzusammenhang, welche Information die vollständige SQL-Anweisung liefert.
Lösung: Im Sachzusammenhang werden die Streckenabschnitte mit der längsten Fahrzeit ermittelt. Es wird jeweils die ID der Bahnlinie, der vonBahnhofName, der zuBahnhofname und die Fahrzeit ausgegeben.
d) Analysieren Sie die Methode und erläutern Sie, wie sie arbeitet, wobei Sie die SQL-Anweisung in Zeile 4 einbeziehen.
Lösung: Die SQL-Abfrage liefert alle Datensätze aus der Tabelle gehoertZu. In Zeile 2 wird 'gefunden' mit false, in Zeile 3 'anzahl' mit 1 initialisiert. Falls fehlerfrei und nicht leer, werden die Zeilen durchlaufen. Stimmt die Bahnlinie-ID mit pID überein, wird 'anzahl' um 1 erhöht und 'gefunden' auf true gesetzt. Falls kein Datensatz gefunden wurde, wird 'anzahl' auf -1 gesetzt. Am Ende wird 'anzahl' zurückgegeben.
d) Rückgabe der Methode für pID = "L1":
Lösung: 4
d) Rückgabe der Methode für pID = "L3":
Lösung: 2
d) Rückgabe der Methode für pID = "L5":
Lösung: -1
d) Erläutern Sie bezogen auf den Sachkontext, welche Information die Methode bestimmt.
Lösung: Im Sachkontext liefert die Methode die Anzahl der Bahnhöfe für eine im Parameter übergebene ID einer Bahnlinie. Falls es zu dieser ID keine Einträge gibt, wird der Wert -1 zurückgeliefert.
d) Entscheiden Sie, ob sich die von der Methode gelieferte Information auch mit einer SQL-Anweisung bestimmen lässt, sodass keine Schleife nötig ist.
Lösung: Ja, die gleiche Information könnte man mit einer SQL-Anweisung ermitteln, wenn man die Aggregatfunktion COUNT verwendet und in der WHERE-Klausel die ID der Bahnlinie mit der im Parameter übergebenen ID der Bahnlinie pID vergleicht.
Die ausführliche Erklärung Schritt für Schritt (mit KI) gibt es mit Premium. Premium
Löse sie direkt hier: automatische Korrektur, Hinweise und Lösung Schritt für Schritt.
Aufgabe 3 - SQL-Abfragen · GK · Haupttermin · Weiterbildungskolleg 2023 ›
Mehr Aufgaben zu SQL-Abfragen
- Aufgabe 3 - SQL-Abfragen · GK · Haupttermin · Weiterbildungskolleg 2023
- Aufgabe 3 - SQL-Abfragen und Auswertung in Java · GK · Nachtermin 2023
- Aufgabe 3 - SQL-Abfragen · LK · Haupttermin 2023
- Aufgabe 3 - SQL-Abfragen · LK · Haupttermin · Weiterbildungskolleg 2023
- Aufgabe 3 - SQL-Abfragen · LK · Nachtermin 2023
- Aufgabe 3 - SQL-Abfragen · GK · Haupttermin 2022
- Aufgabe 3 - SQL-Abfragen · GK · Nachtermin 2022
- Aufgabe 3 - SQL-Abfragen · LK · Haupttermin 2022
- Aufgabe 3 - SQL-Abfragen · LK · Nachtermin 2022
- Aufgabe 3 - SQL-Abfragen · GK · Haupttermin 2021