Hallo Gemeinde,
Die Kurzfassung: Ich habe eine Tabelle, in die zu einem mehrspaltigen
Schlüssel Werte eingetragen sind. Zur graphischen Darstellung möchte
ich, dass zu allen kombinatorisch möglichen Schlüsseln ein Eintrag
existiert, dass also für die Schlüssel, zu denen kein „echter“ Wert
existiert, 0 eingetragen wird. Dafür suche ich einen effizienten
Algorithmus.
Und jetzt ausführlich:
Als selbständiger Handelsvertreter bekomme ich von meinem Auftraggeber
jeden Monat eine Liste, in der die Monatsumsätze jedes Kunden in meinem
Gebiet enthalten sind. Monatliche Listen sind nicht hilfreich, um die
Übersicht über mehrere Jahre zu behalten. Ich schreibe mir daher gerade
ein kleines JavaFX-Tool, das Umsätze und Umsatzverläufe graphisch darstellt.
Ich habe also eine Postgresql-Datenbank angelegt, in die ich die
monatlichen Listen importiere. Ich benutze drei Tabellen:
institutions enthält die Kunden und hat die spalten key, name,
postalcode, city, street. key ist eine eindeutige ID, die von der
Software des Auftraggebers vergeben wird. key wird als Primärschlüssel
benutzt.
products hat eine Spalte name und enthält alle vorkommenden Produktnamen.
sales hat die Spalten key, product, sales, month, year, hv. key ist ein
Foreign key und bezieht sich auf institutions.key. product ist ein
foreign key und bezieht sich auf
products.name. Der primary key ist
(month, year, hv, key, product).
Die vierte Tabelle ist für dieses Problem ohne Bedeutung.
Das Tool zeigt in den entsprechenden Graphen Linienverbindungen zwischen
existierenden Punkten. Das irritiert, da nicht jeder Kunde jedes Produkt
in jedem Monat bestellt. Ich hätte also gerne Nulleinträge für jeden
primary key. Die fehlenden Einträge kann ich aber nicht auf trivialem
Weg eingeben, da sie eben fehlen und daher nicht auswählbar sind.
Meine existierende Lösung funktioniert, ist aber alles andere als
effizient. Ich erzeuge jeden möglichen Schlüssel und trage 0 ein.
Existiert schon ein Wert, wird das Überschreiben mit einer ON
CONFLICT-Klausel verhindert.
String sql = "insert into sales (select distinct on (sales.month,
sales.year,
products.name, institutions.key) institutions.key,
products.name, '0' as sales, '0' as provision, sales.month, sales.year,
" + hVName + " as hv from sales cross join products cross join
institutions) on conflict on constraint main do nothing;"
Das dauert natürlich. Nicht zuletzt, weil jeder bereits existierende
Datensatz angefasst werden muss.
Gibt es da elegantere Möglichkeiten? Ich habe mir auch überlegt, den
Vorgang außerhalb der Datenbank in Java durchzuführen und nur die neuen
Null-Zeilen einzutragen. Aber eigentlich sollte ein DBMS sowas intern
effizienter durchführen als ein externes Tool, dafür ist es doch da?
TIA
QNo