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]

Aufgabenstellung: Aufgabe 3 - SQL-Abfragen · Abitur NRW Informatik GK · Haupttermin 2023

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