\documentclass{bschlangaul-aufgabe} \bLadePakete{rmodell,syntax,relationale-algebra} \begin{document} \bAufgabenMetadaten{ Titel = {Aufgabe 2}, Thematik = {Medikamente}, Referenz = 66116-2019-F.T1-TA1-A2, RelativerPfad = Examen/66116/2019/03/Thema-1/Teilaufgabe-1/Aufgabe-2.tex, ZitatSchluessel = examen:66116:2019:03, BearbeitungsStand = mit Lösung, Korrektheit = unbekannt, Ueberprueft = {unbekannt}, Stichwoerter = {SQL, SQL mit Übungsdatenbank, Relationale Algebra}, EinzelpruefungsNr = 66116, Jahr = 2019, Monat = 03, ThemaNr = 1, TeilaufgabeNr = 1, AufgabeNr = 2, } \let\a=\bAttribut \let\f=\bFremd \let\p=\bPrimaer \let\r=\bRelationMenge Gegeben sei der folgende Ausschnitt des Schemas für die Verwaltung der Einnahme von Medikamenten: \index{SQL} \footcite{examen:66116:2019:03} \begin{bRelationenModell} \r{Person}{ ID : INTEGER, Name : VARCHAR(255), Wohnort : VARCHAR(255) } \r{Hersteller}{ ID : INTEGER, Name : VARCHAR(255), Standort : VARCHAR(255), AnzahlMitarbeiter : INTEGER } \r{Medikament}{ ID : INTEGER Name : VARCHAR(255), Kosten : INTEGER, Wirkstoff : VARCHAR(255), produziert\_von : INTEGER } \r{nimmt}{ Person : INTEGER, Medikament : INTEGER, von : DATE, bis : DATE } \r{hat\_Unverträglichkeit\_gegen}{ Person : INTEGER, Medikament : INTEGER } \end{bRelationenModell} % Datenbankname: medikamente \begin{minted}{sql} CREATE TABLE Person ( ID INTEGER PRIMARY KEY, Name VARCHAR(255), Wohnort VARCHAR(255) ); CREATE TABLE Hersteller ( ID INTEGER PRIMARY KEY, Name VARCHAR(255), Standort VARCHAR(255), AnzahlMitarbeiter INTEGER ); CREATE TABLE Medikament ( ID INTEGER PRIMARY KEY, Name VARCHAR(255), Kosten INTEGER, Wirkstoff VARCHAR(255), produziert_von INTEGER REFERENCES Hersteller(ID) ); CREATE TABLE nimmt ( Person INTEGER, Medikament INTEGER, von DATE, bis DATE, PRIMARY KEY (Person, Medikament, von, bis) ); CREATE TABLE hat_Unverträglichkeit_gegen ( Person INTEGER REFERENCES Person(ID), Medikament INTEGER REFERENCES Medikament(ID) ); INSERT INTO Person VALUES (1, 'Walter Müller', 'Holzapfelkreuth'), (2, 'Dilara Yildiz', 'Fürth'); INSERT INTO Hersteller VALUES (1, 'Hexal', 'Holzkirchen', 3700), (2, 'Ratiopharm', 'Ulm', 563); INSERT INTO Medikament VALUES (1, 'IbuHexal', 3, 'Ibuprofen', 1), (2, 'Ratio-Paracetamol', 2, 'Paracetamol', 2), (3, 'BudeHexal', 4, 'Budesonid', 1), (4, 'Ratio-Budesonid', 5, 'Budesonid', 2); INSERT INTO nimmt VALUES (1, 1, '2021-07-12', '2021-07-23'), (1, 3, '2021-07-12', '2021-07-23'), (2, 4, '2021-02-13', '2021-03-24'); INSERT INTO hat_Unverträglichkeit_gegen VALUES (1, 1), (1, 3), (2, 2); \end{minted} \index{SQL mit Übungsdatenbank} Die Tabelle \a{Person} beschreibt Personen über eine eindeutige ID, deren Namen und Wohnort. Die Tabelle \a{Medikament} enthält Informationen über Medikamente, unter anderem deren Namen, Kosten, Wirkstoffe und einen Verweis auf den Hersteller dieses Medikaments. Die Tabelle \a{Hersteller} verwaltet verschiedene Hersteller von Medikamenten. Die Tabelle \a{hat\_Unverträglichkeit\_gegen} speichert die IDs von Personen zusammen mit den IDs von Medikamenten, gegen die diese Person eine Unverträglichkeit hat. Die Tabelle \a{nimmt} hingegen verwaltet die Einnahme der verschiedenen Medikamente und speichert zudem in welchem Zeitraum eine Person welches Medikament genommen hat bzw. nimmt. Beachten Sie bei der Formulierung der SQL-Anweisungen, dass die Ergebnisrelationen keine Duplikate enthalten dürfen. Sie dürfen geeignete Views definieren. \begin{enumerate} %% % a) %% \item Schreiben Sie SQL-Anweisungen, die für die bereits existierende Tabelle \a{nimmt} alle benötigten Fremdschlüsselconstraints anlegt. Erläutern Sie kurz, warum die Spalten \a{von} und \a{bis} Teil des Primärschlüssels sind. \begin{bAntwort} \begin{minted}{sql} ALTER TABLE nimmt ADD CONSTRAINT FK_Person FOREIGN KEY (Person) REFERENCES Person(ID), ADD CONSTRAINT FK_Medikament FOREIGN KEY (Medikament) REFERENCES Medikament(ID); \end{minted} \end{bAntwort} %% % b) %% \item Schreiben Sie eine SQL-Anweisung, welche sowohl den \a{Namen} als auch die \a{ID} von \a{Personen} und \a{Medikamenten} ausgibt, bei denen die Person das jeweilige Medikament nimmt. \begin{bAntwort} \begin{minted}{sql} SELECT DISTINCT p.ID as Personen_ID, p.Name as Personen_Name, m.ID as Medikamenten_ID, m.Name as Medikamenten_Name FROM Person p, Medikament m, nimmt n WHERE n.Person = p.ID AND n.Medikament = m.ID; \end{minted} \end{bAntwort} %% % c) %% \item Schreiben Sie eine SQL-Anweisung, welche die ID und den Namen der Medikamente mit den niedrigsten Kosten je Hersteller bestimmt. \begin{bAntwort} \begin{minted}{sql} SELECT m.ID, m.Name FROM Medikament m, Medikament n WHERE m.produziert_von = n.produziert_von AND m.Kosten >= n.Kosten GROUP BY m.ID, m.Name HAVING COUNT(*) <= 1; \end{minted} \end{bAntwort} %% % d) %% \item Schreiben Sie eine SQL-Anweisung, die die Anzahl aller Personen ermittelt, die ein Medikament genommen haben, gegen welches sie eine Unverträglichkeit entwickelt haben. \begin{bAntwort} \begin{minted}{sql} SELECT COUNT(DISTINCT p.ID) FROM Person p, nimmt n, hat_Unverträglichkeit_gegen u WHERE p.ID = n.Person AND u.Medikament = n.Medikament; \end{minted} \end{bAntwort} %% % %% \item Schreiben Sie eine SQL-Anweisung, die die ID und den Namen derjenigen Personen ermittelt, die weder ein Medikament mit dem Wirkstoff Paracetamol noch ein Medikament mit dem Wirkstoff Ibuprofen genommen haben. \begin{bAntwort} \begin{minted}{sql} SELECT ID, Name FROM Person EXCEPT SELECT p.ID, p.Name FROM Person p, nimmt n, Medikament m WHERE p.ID = n.Person AND n.Medikament = m.ID AND m.Wirkstoff IN ('Ibuprofen', 'Paracetamol'); \end{minted} \end{bAntwort} %% % %% \item Schreiben Sie eine SQL-Anweisung, welche die Herstellernamen und die Anzahl der bekannten Unverträglichkeiten gegen Medikamente dieses Herstellers ermittelt. Das Ergebnis soll aufsteigend nach der Anzahl der bekannten Unverträglichkeiten sortiert werden. \begin{bAntwort} \begin{minted}{sql} SELECT p.Name, ( SELECT COUNT(h.ID) FROM Hersteller h, Medikament m, hat_Unverträglichkeit_gegen u WHERE m.produziert_von = h.ID AND u.Medikament = m.ID AND h.ID = p.ID ) AS Unverträglichkeiten FROM Hersteller p ORDER BY Unverträglichkeiten ASC; \end{minted} \end{bAntwort} %% % %% \item Formulieren Sie eine Anfrage in relationaler Algebra, welche die Wohnorte aller Personen bestimmt, welche ein Medikament mit dem Wirkstoff Paracetamol nehmen oder genommen haben. Die Lösung kann als Baum- oder als Term-Schreibweise angegeben werden. \index{Relationale Algebra} \begin{bAntwort} $\pi_{\text{Person.Wohnort}} \left( \sigma_{\text{Medikament.Wirkstoff }= '\text{Paracetamol}'} ( \text{Person} \bowtie_{\text{Person.ID} = \text{nimmt.Person}} \text{nimmt} \bowtie_{\text{nimmt.Medikament} = \text{Medikament.ID}} \text{Medikament} ) \right)$ \end{bAntwort} %% % %% \item Formulieren Sie eine Anfrage in relationaler Algebra, welche die Namen aller Personen bestimmt, die von allen bekannten Herstellern, deren Standort München ist, Medikamente nehmen oder genommen haben. Die Lösung kann als Baum- oder als Term-Schreibweise angegeben werden. \begin{bAntwort} \begin{bAntwort} $\pi_{\text{Person.Name}} \left( \sigma_{\text{Hersteller.Standort }= '\text{München}'} ( ( \text{Person} \bowtie_{\text{Person.ID} = \text{nimmt.Person}} \text{nimmt} ) \bowtie_{\text{nimmt.Medikament} = \text{Medikament.ID}} ( \text{Medikament} \bowtie_{\text{Medikament.produziert\_von} = \text{Hersteller.ID}} \text{Hersteller} ) ) \right)$ \end{bAntwort} \end{bAntwort} \end{enumerate} \end{document}