Einführung
PAPER & PIER benötigt eine Übergabe zum Geschäftsschluss: eine CSV-Zeile pro Bestellung und eine Zusammenfassung für jeden Stand. Beide Stände können insgesamt eine Differenz von null aufweisen, während einzelne Bestellungen weiterhin unter- oder überbezahlt sind. Die Übergabe muss diese Ausnahmen bewahren, statt aus einer einzigen Gesamtsumme Erfolg abzuleiten.
Du speicherst eine wiederverwendbare SQL-Abfrage und erstellst mit dem bereitgestellten Exportprogramm echte CSV-Dateien aus ihren tatsächlichen Ergebnissen. Schließe zuerst „Jede Bestellsumme korrekt halten“ ab oder bringe Kenntnisse zu SUM/GROUP BY, LEFT JOIN, COALESCE und dem Problem vervielfachender Joins mit. Common Table Expressions und die Statusklassifizierung werden hier erklärt. Verwende durchgehend Terminal; diese Einheit hat ihr eigenes unabhängiges Geschäftsbuch mit sechs Bestellungen.
Lass alle vier Quelltabellen und bereitgestellten Werkzeuge unverändert. Ändere nur query.sql und Dateien unter reports/; füge keine Datenbankobjekte hinzu. Alle Geldbeträge sind ganzzahlige Centwerte. Dies ist ein vereinfachter Abgleich von Einnahmen, ohne Steuern oder Zahlungsdienstleister-Abrechnung. Das Exportprogramm übernimmt die CSV-Kodierung und die Berechnung der Zusammenfassung; du musst kein Python schreiben.
Eine wiederverwendbare Abfrage pro Bestellung speichern
In diesem Schritt berechnest du die Nettoeinnahmen, die Differenz und den Status jeder Bestellung mit einer einzigen eigenständigen SQL-Anweisung. Beginne in Terminal:
cd /home/labex/project/sales-desk
sqlite3 -header -column ledger.db "SELECT * FROM orders ORDER BY order_id;"
Dieses unabhängige Geschäftsbuch enthält A1 bis A6, darunter zwei Bestellungen mit der Bezeichnung Alex Kim sowie Bezeichnungen mit Kommas oder Anführungszeichen. IDs unterscheiden die Bestellungen; bewahre Bezeichnungen exakt wie gespeichert. Prüfe jede Faktenliste, bevor du Salden ableitest:
sqlite3 -header -column ledger.db "SELECT * FROM items ORDER BY item_id; SELECT * FROM payments ORDER BY payment_id; SELECT * FROM refunds ORDER BY refund_id;"
Wie zuvor zählen nur Zahlungen und Erstattungen mit succeeded. Zwei erfolgreiche Ereignisse mit gleichen Beträgen zählen beide. Fehlende berücksichtigungsfähige Fakten tragen null bei. Die Berechnung lautet:
| Ausgabe | Definition |
|---|---|
due_cents |
Summe aus Artikelmenge multipliziert mit Stückpreis in Cent |
paid_cents |
Summe der Centbeträge erfolgreicher Zahlungen |
refunded_cents |
Summe der Centbeträge erfolgreicher Erstattungen |
net_cents |
Bezahlt minus erstattet |
difference_cents |
Netto minus fällig |
status |
settled bei Differenz null, underpaid bei negativer, overpaid bei positiver Differenz |
Eine Common Table Expression (CTE) ist ein benanntes Zwischen-SELECT, das nur innerhalb einer Anweisung verfügbar ist. WITH name AS (...) führt es ein; Kommas trennen mehrere CTEs. Es ermöglicht dieselbe Trennung der Fakten wie die vorherigen Views, ohne Datenbankobjekte zu erstellen oder von Dateien eines anderen Labs abzuhängen.
Zuerst aggregieren drei CTEs jede Faktenart unabhängig. Dann beginnt totals mit den Bestellungen und ergänzt fehlende Summen mit null. balances berechnet Netto und Differenz aus diesen benannten Summen. Das letzte SELECT verwendet CASE WHEN ... THEN ... ELSE ... END, um den Status anhand des Vorzeichens der Differenz auszuwählen. Diese Ebenen stellen Aliasse dem folgenden SELECT zur Verfügung, statt sich auf den Alias eines anderen Ausdrucks in derselben SELECT-Liste zu verlassen. SELECT * in der Zwischenebene für Salden übernimmt die Summen; das abschließende SELECT listet ausdrücklich genau neun Spalten in der erforderlichen Reihenfolge auf.
Speichere die vollständige Anweisung. cat > ersetzt die Datei; das Here-Dokument mit Anführungszeichen bewahrt SQL wörtlich. Füge die abschließende Zeile SQL ein:
cat > query.sql <<'SQL'
WITH
item_totals AS (
SELECT order_id, SUM(quantity * unit_cents) AS due_cents
FROM items GROUP BY order_id
),
payment_totals AS (
SELECT order_id, SUM(amount_cents) AS paid_cents
FROM payments WHERE status = 'succeeded' GROUP BY order_id
),
refund_totals AS (
SELECT order_id, SUM(amount_cents) AS refunded_cents
FROM refunds WHERE status = 'succeeded' GROUP BY order_id
),
totals AS (
SELECT o.order_id, o.customer, o.stall,
COALESCE(i.due_cents, 0) AS due_cents,
COALESCE(p.paid_cents, 0) AS paid_cents,
COALESCE(r.refunded_cents, 0) AS refunded_cents
FROM orders AS o
LEFT JOIN item_totals AS i ON i.order_id = o.order_id
LEFT JOIN payment_totals AS p ON p.order_id = o.order_id
LEFT JOIN refund_totals AS r ON r.order_id = o.order_id
),
balances AS (
SELECT *, paid_cents - refunded_cents AS net_cents,
paid_cents - refunded_cents - due_cents AS difference_cents
FROM totals
)
SELECT order_id, customer, stall, due_cents, paid_cents,
refunded_cents, net_cents, difference_cents,
CASE WHEN difference_cents = 0 THEN 'settled'
WHEN difference_cents < 0 THEN 'underpaid'
ELSE 'overpaid' END AS status
FROM balances
ORDER BY order_id;
SQL
Füge keine SQLite-Punktbefehle oder Shell-Befehle in query.sql ein: Das Exportprogramm führt eine gewöhnliche SELECT/WITH-Anweisung aus. Sie muss aus den vier Quelltabellen auf einem weiteren Geschäftsbuch mit demselben Schema funktionieren, auch bei anderen Bestell-IDs und Beträgen. Fest kodierte Ergebniszeilen oder Datenbank-Views würden diese wiederverwendbare Abfrage nicht liefern.
< übergibt diese Datei an die SQLite-CLI für einen lesbaren ersten Lauf:
sqlite3 -header -column ledger.db < query.sql
Lies die tatsächlichen Zeilen, nicht nur eine Summe. Erwartete Salden sind:
| Bestellung | Fällig | Netto | Differenz | Status |
|---|---|---|---|---|
| A1 | 800 | 800 | 0 | settled |
| A2 | 250 | 0 | -250 | underpaid |
| A3 | 500 | 500 | 0 | settled |
| A4 | 200 | 250 | 50 | overpaid |
| A5 | 600 | 850 | 250 | overpaid |
| A6 | 400 | 350 | -50 | underpaid |
A2 bleibt ohne Zahlung sichtbar. A3 behält beide erfolgreichen Erstattungen über je 50 Cent. Die fehlgeschlagene Erstattung von A6 verringert dessen Nettoeinnahmen nicht. A1 und A2 bleiben getrennt, obwohl sie dieselbe Kundenbezeichnung haben. Alle fünf Cent-Spalten sind tatsächliche Ganzzahlen, einschließlich negativer Differenzen; wandle sie nicht in formatierte Währungszeichenfolgen um.
Lies bei einem Syntaxfehler die gemeldete Stelle und ersetze query.sql vor dem erneuten Ausführen durch den korrigierten vollständigen Block. Kehre bei einem falschen Pfad mit dem absoluten cd oben zurück und verwende ls, um query.sql zu finden. Leere nicht das Geschäftsbuch, ändere keine Beträge, um einen Ausgleich zu erzwingen, und füge keine gespeicherten Ergebnistabellen hinzu.
Die tatsächlichen CSV-Dateien übergeben und lesen
In diesem Schritt exportierst du die gespeicherte Abfrage und liest ihre echten Übergabedateien, einschließlich Bezeichnungen, die CSV-Anführungszeichen benötigen. Beginne in Terminal im Verzeichnis /home/labex/project/sales-desk.
./export ist ein bereitgestelltes ausführbares Programm im aktuellen Verzeichnis. Es liest query.sql, führt diese unveränderte Anweisung über eine schreibgeschützte Verbindung gegen ledger.db aus und schreibt die tatsächlich zurückgegebenen Zeilen nach reports/orders.csv. Es leitet reports/summary.csv ausschließlich aus diesen zurückgegebenen Zeilen ab. Es repariert keine falsche Abfrage und ergänzt keine fehlenden Bestellungen. Das vorbereitete Verzeichnis reports ist der Ablageort für beide Dateien:
./export
Die Meldung nennt sechs Abfragezeilen und beide Ausgabedateien. Das unten verwendete Leseprogramm zeigt zwei Standzusammenfassungen. Ein erfolgreicher Export bedeutet, dass Dateien geschrieben wurden, nicht, dass deine Berechnung korrekt ist. Fehlt die Abfrage oder ist sie ungültig, meldet das Exportprogramm einen Fehler. Alte Dateien eines früheren erfolgreichen Exports können weiterhin vorhanden sein: Korrigiere die gespeicherte Abfrage und führe ./export erneut aus, bevor du sie als aktuell betrachtest.
./review ist das bereitgestellte CSV-Leseprogramm. Es liest die gespeicherten Dateien ohne Rückgriff auf die Datenbank und zeigt jede eingelesene Zeile als beschrifteten Datensatz an. Fehlende oder veränderte Ausgaben bleiben fehlend oder verändert:
./review
Die sechs Bestelldatensätze sollten mit der Tabelle aus dem vorherigen Schritt übereinstimmen, mit exakt den ursprünglichen Kunden- und Standbezeichnungen. Die Zusammenfassungsspalten sind:
| Spalte | Bedeutung |
|---|---|
stall |
Exakte Standbezeichnung |
order_count |
Anzahl der zurückgegebenen Bestellungen dieses Stands |
due_cents, net_cents, difference_cents |
Summen der entsprechenden Bestellspalten |
settled_count, underpaid_count, overpaid_count |
Anzahlen der entsprechenden Bestellstatus |
North, Pier hat drei Bestellungen: fällig 1650, netto 1650, Differenz 0 und je eine mit jedem Status. South hat ebenfalls drei: fällig 1100, netto 1100, Differenz 0 und je eine mit jedem Status. Über beide Stände hinweg gibt es vier nicht ausgeglichene Bestellungen, obwohl die Gesamtdifferenz null ist. Über- und Unterzahlungen heben sich in einer Summe auf; sie gleichen nicht die Bestellung einer anderen Person aus.
CSV bedeutet durch Kommas getrennte Werte, aber ein Komma innerhalb einer Bezeichnung gehört zu einem einzigen Feld. Standard-CSV umschließt solche Felder mit doppelten Anführungszeichen und stellt ein Anführungszeichen innerhalb eines Felds durch zwei Anführungszeichen dar. cat zeigt die rohen Dateibytes als Text; vergleiche diese Kodierung mit den korrekt eingelesenen Bezeichnungen aus ./review:
cat reports/orders.csv
cat reports/summary.csv
In der Bestelldatei ist die Kundenbezeichnung Paper, "Pine" als "Paper, ""Pine""" kodiert; North, Pier ist als "North, Pier" kodiert. Diese zusätzlichen Anführungszeichen sind CSV-Syntax, keine Änderungen an den Bezeichnungen. Jede Zeile an jedem Komma aufzutrennen, würde diese Datensätze beschädigen; das bereitgestellte Schreib- und Leseprogramm verarbeitet das Format.
Fehlt eine CSV-Datei, führe erneut ./export aus, nachdem du query.sql korrigiert hast, und lies anschließend beide Dateien noch einmal. Bearbeite keine Zusammenfassung von Hand, um fehlende Bestellungen zu verbergen, ersetze weder Export- noch Leseprogramm und ändere keine Quelldatensätze. Deine Übergabe besteht aus der wiederverwendbaren query.sql und beiden echten CSV-Dateien. Die Dateien sollten eine Zeile für jede Quellbestellung, die exakten neun Bestellspalten und die acht oben gezeigten Zusammenfassungsspalten enthalten. Die Zeilenreihenfolge ist nicht das fachliche Ergebnis; entscheidend sind Identitäten, Werte, Bezeichnungen und ihre Beziehungen.
Zusammenfassung
Du hast eine wiederverwendbare CTE-Abfrage erstellt, jede Bestellung anhand der Nettoeinnahmen abzüglich ihres Warenwerts klassifiziert und zwei echte CSV-Dateien übergeben. Du hast korrekt in Anführungszeichen gesetzte Bezeichnungen gelesen und ausgeglichene Standsummen von einzeln ausgeglichenen Bestellungen unterschieden.



