-- Erstellen Sie SQL-Abfragen für die folgenden Aufgaben (Queries geben einen Punkt, sofern nicht anders angegeben):

-- 1) Selektieren Sie die Employee ID, Vornamen und Nachname aller Angestellten - sortieren Sie absteigend nach Nachname und dann nach Vorname.
SELECT emp_id, fname, lname
FROM employee
ORDER BY lname DESC, fname DESC;

-- 2) Holen Sie Kontonummer, Kundennummer und Kontostand für alle aktiven Konten mit mehr als 2500 Dollar (nutzen Sie als Kontostand avail_balance).
SELECT
    account_id,
    cust_id,
    avail_balance
FROM account
WHERE
    status = 'ACTIVE'
    AND avail_balance > 2500;

-- 3) Holen Sie aus der Tabelle account alle IDs der Angestellten, die ein Konto eröffnet haben - geben Sie dabei jede ID nur einmal aus (Tipp: DISTINCT).
SELECT a.open_emp_id AS emp_id FROM account a GROUP BY a.open_emp_id;

-- 4) Zählen Sie die Zeilen in der account-Tabelle.
SELECT COUNT(a.account_id) AS Anzahl_Zeilen FROM account a;

-- 5) Geben Sie eine Tabelle aus, in der, in der ersten Spalte der Name des Kunden und in einer zweiten Spalte die Anzahl Konten dieses Kunden steht - Hinweis: hier reicht es aus, die Namen der Individualkunden zu verwenden (individual), Geschäftskunden dürfen ignoriert werden.
CREATE OR REPLACE VIEW AUFGABE_5 AS -- Der View ist hier nur für Aufgabe 6

SELECT CONCAT(i.lname, ' ', i.fname) AS Kunden_Name, COUNT(a.account_id) AS Anzahl_Konten
FROM account a
    JOIN individual i ON i.cust_id = a.cust_id
GROUP BY
    i.cust_id;

-- 6) Wie 5), aber zeigen Sie nur Kunden an, die 2 oder mehr Konten haben.

-- Kleiner Trick ^-^, Aufgabe 5 als View verwenden:
SELECT * FROM AUFGABE_5 WHERE Anzahl_Konten >= 2;

-- Alternative Lösung:
SELECT CONCAT(i.lname, ' ', i.fname) AS Kunden_Name, COUNT(a.account_id) AS Anzahl_Konten
FROM account a
    JOIN individual i ON i.cust_id = a.cust_id
GROUP BY
    i.cust_id
HAVING
    COUNT(a.account_id) >= 2;

-- 7) Geben Sie eine Query an, die alle Accounts findet, die im Jahr 2002 eröffnet wurden, ohne die Symbole > oder < zu verwenden.
SELECT *
FROM account a
WHERE
    a.open_date BETWEEN TIMESTAMP '2002-01-01' AND TIMESTAMP  '2003-01-01';

-- 8) Geben Sie eine Query an, die alle Kunden ("individual") findet, deren Nachname an der zweiten Stelle ein 'a' danach an beliebiger Stelle ein 'e' enthält.
SELECT * FROM individual i WHERE REGEXP_LIKE(i.lname, '^.a.*e');

-- 9) Schreiben Sie eine Query, die alle Account-IDs für jeden Nicht-Geschäftskunden holt,
-- dazu die fed_id des Kunden und den Namen des Produkts, auf dem der Account basiert.
SELECT a.account_id, c.fed_id, p.name
FROM
    customer c
    JOIN account a ON c.cust_id = a.cust_id
    JOIN product p ON a.product_cd = p.product_cd
WHERE
    c.cust_type_cd != 'B';

-- 10) Schreiben Sie eine Query, die alle Angestellten findet,
-- deren Supervisor in einer anderen Abteilung (department) arbeitet.
-- Selektieren Sie ID, Vor- und Nachname.
SELECT e.emp_id AS ID, e.fname AS Vorname, e.lname AS Nachname
FROM employee e
    JOIN employee e2 ON e.superior_emp_id = e2.emp_id
WHERE
    e.dept_id != e2.dept_id;

-- 11) (2 Punkte) Selektieren Sie alle Vornamen und Nachnamen in einer Tabelle
-- (sowohl die der Individual-Kunden als auch die der Angestellten).
-- Tipp: Machen Sie sich mit der UNION-Anweisung vertraut.
SELECT fname, lname
FROM individual
UNION
SELECT fname, lname
FROM employee;

-- 12) (2 Punkte) Selektieren Sie folgende Tabelle: Vorgesetzter (Name), komma-getrennte Liste der Mitarbeiter,
-- die zu einem Vorgesetzten gehören.
SELECT
    sup.lname AS Vorgesetzter,
    STRING_AGG (
        CONCAT(emp.fname, ' ', emp.lname),
        ', '
    ) AS Mitarbeiter
FROM employee emp
    JOIN employee sup ON emp.superior_emp_id = sup.emp_id
GROUP BY
    sup.emp_id;

-- 13) (2 Punkte) Selektieren Sie alle Account-IDs und die dazugehörige Customer-ID.
-- Wenn es ein Geschäftskunde ist, dann soll noch der Firmenname in der dritten Spalte stehen,
-- sonst soll in der dritten Spalte der Vor- und Nachname des Privatkunden stehen (Tipp: COALESCE).
SELECT c.cust_id,
       STRING_AGG(a.account_id::text, ', ') AS Accounts,
       COALESCE(b.name, CONCAT(i.fname, ' ', i.lname)) AS Kundenname
FROM account a
JOIN customer c ON a.cust_id = c.cust_id
LEFT JOIN business b ON c.cust_id = b.cust_id
LEFT JOIN individual i ON c.cust_id = i.cust_id
GROUP BY c.cust_id, b.name, CONCAT(i.fname, ' ', i.lname);

-- 14) (2 Punkte) Selektieren Sie den Namen des Kunden mit dem höchsten Gesamtvermögen (nur eine Gesamt-Query - Subqueries dürfen genutzt werden)
SELECT SUM(a.avail_balance) AS "Gesamtvermögen", COALESCE(
        b.name, CONCAT(i.fname, ' ', i.lname)
    ) AS Kundenname
FROM
    customer c
    JOIN account a ON c.cust_id = a.cust_id
    LEFT JOIN individual i ON c.cust_id = i.cust_id
    LEFT JOIN business b ON c.cust_id = b.cust_id
GROUP BY
    c.cust_id,
    b.name,
    i.fname,
    i.lname
ORDER BY SUM(a.avail_balance) DESC
LIMIT 1;

-- 15) (2 Punkte) Selektieren Sie alle Namen der Bank-Produkte (Tabelle product, Verbindung product_cd)
-- mit den Accounts (account_id), die auf diesem Produkt basieren.
-- Dabei sollen alle Produkte auftauchen, auch die ohne Account.
SELECT p.name AS Produktname,
       STRING_AGG(a.account_id::text, ', ') AS Accounts
FROM product p
LEFT JOIN account a ON p.product_cd = a.product_cd
GROUP BY p.product_cd;
