Wertekombination nur einmalig anzeigen

Hallo Fachleute,

Ich habe ein SQL-Problem (Ora-10g) und überhaupt keine Idee, wie ich das lösen kann.
Gegeben sei Tabelle, die im Auszug folgende Daten enthält:

SPALTE1 SPALTE2

1000 A
1000 B
1000 D

1005 A
1005 C
1005 D

1010 B
1010 C
1010 D

1015 B
1015 C

1020 A

1025 E

Ich möchte nun alle Datensätze angezeigt bekommen, deren Werte-Kombination in Spalte2 noch nicht vorgekommen ist.

Zur Verdeutlichung eine etwas andere Darstellung:

1000 A B D wird angezeigt, da Kombination eindeutig
1005 A C D wird angezeigt, da Kombination eindeutig
1010 B C D wird angezeigt, da Kombination eindeutig
1015 B C nicht anzeigen, da bereits in 1010 enthalten
1020 A nicht anzeigen, da bereits in 1000 und 1005 enthalten
1025 E wird angezeigt, da Kombination eindeutig

Leider ist weder die Anzahl der möglichen (eindeutigen) Werte in Spalte1, noch die Anzahl der Werte je Spalte1-Wert vorhersagbar.

Würde es in Spalte1 einen Wert geben, der in Spalte2 die Inhalte A, B, C, D und E vereint, würde natürlich nur der Wert mit seinen 5 Spalte2-Werten angezeigt, da ja alle Kombinationen „erschlagen“ sind.

So. Ich hoffe, ich konnte mein Problem deutlich genug beschreiben und dass ihr eine Idee oder vllt. sogar Lösung für mich habt…. :wink:

viele Grüße

hallo

kommt drauf an, wie oft du diese abfrage brauchst und wie oft sich die basiswerte ändern.

eine halbwegs praktikable lösung wäre, eine zwischentabelle aufzubauen, die die daten aus deiner tabelle denormalisiert (muss vermutlich mit pl/sql erfolgen). dann kannst du diese tabelle halbwegs sinnvoll auswerten.

nachteil: die neue tabelle muss immer wieder neu erzeugt werden - zumindest wenn sich die daten ändern.

geht auch mit views und entsprechend präparierten stored functions. wird allerdings bei grossen datenmengen recht langsam und belastet die datenbank enorm.

wirklich sinnvoll lösbar ist das problem nicht - du willst da einen statistische auswertung, die recht umfangreich ist. ohne programmieren (also nur reines sql) wird es ziemlich sicher nicht gehen.

lg
erwin

Hallo Karsten,

ohne die Angaben von Erwin in irgendeinerweise in Frage zu stellen (eher zu unterstreichen): Du willst eine beliebig große n*n Matrix mit simplen SQL aufbauen (denn ohne Angabe, wieviele Ausprägungen die Spalte 2 haben kann, muss man worst case davon ausgehen, dass sie identisch mit Anzahl n der distincten Elemente in Spalte 1 sind)?
Okay: Kannst Du denn etwas zu dem Hintergrund dieser Abfrage erzählen (z.B. die Angabe, die Erwin gewünscht hat)? Das würde uns ermöglichen ggf. die potentiellen Lösungsmöglichkeiten skizzieren.

MfG Georg V.

P.S.: Deine Darstellung wäre besser gekommen, wenn Du das pre-Tag verwendet hättest.
P.S.2: Was soll nach Deiner Meinung passieren, wenn

1015 B C
1030 B C

in Deiner Auflistung vorkommen: SQL ist eine Sprache für Mengenoperation und keine prozedurale Sprache (es sei denn man weicht auf PL/SQL aus)

P.S.3: Wenn Du Dir eine andere Lösungsvariante aussuchen darfst: Wünsch Dir eine Statistiksoftware wie SAS oder SPSS, damit geht das ruckzuck.

Hallo Erwin,
hallo Georg,

erstmal vielen Dank für eure Antworten. Eine andere Software scheidet leider aus. :frowning:

Die Abfrage wird „on demand“ von einem Frontend aufgerufen. Das Frontend wird von (derzeit) bis zu 30 Usern genutzt, die sporadisch damit arbeiten. Die von mir angegebene „Tabelle“ ist dabei bereits das Ergebnis diverser Vorberechnungen - basierend auf diversen Joins - wobei die größte „Grund-Tabelle“ rund 2 Millionen Datensätze umfasst. Die Vorberechnungen „schlucken“ derzeit rund 0,11 Sekunden.

Je Abfrage-Ergebnis „rechne“ ich mit rund 200 Ergebniszeilen für meine Beispieltabelle.

Als Erläuterung:
Die Basis-Daten könnten z.B. Familien (Spalte 1) darstellen und die Spalte 2 behinhaltet die Familienmitglieder. Dadurch, dass eine Familie mehrfach vorkommen kann (z.B. Schwimmbadbesuch), aber nicht vorhersagbar ist wie oft die Familie und mit welcher Besucherkombination das Schwimmbad besucht, ist die Vorhersage des Datenumfangs sehr schwierig.

Um in diesem Beispiel zu bleiben möchte ich also wissen, in welcher Besucherkombination jede Familie bereits das Schwimmbad benutzt hat. Dabei gilt: Wenn z.B. Mutter und Vater bereits zusammen schwimmen waren, interessiert mich das nur ein mal. Welcher Besuch das genau war, ist irrelevant.

Grundsätzlich ginge ja ein DISTINCT. Aber wie kann ich dann sicherstellen, das zuerst die Spalte1-Werte berücksichtigt werden, die die meisten Spalte2-Werte haben und dann erst die „wegfallen“, die bereits vorkamen. Ein SORT auf die Anzahl der Spalte2-Werte GROUP BY Spalte1 dürfte doch eher zufällig ein korrektes Ergebnis liefern. Oder irre ich mich?

Sollte ich mich irren, wäre mein Problem quasi gelöst, da es mir reicht, einen Spalte2-Wert mit dem passenden Spalte1-Wert zu bekommen. So könnte ich mir alle Spalte1-Ergebnis-Werte erneut vornehmen und die zugehörigen Spalte2-Werte hinzu selektieren.

Meine bisherige Idee wäre gewesen:

  • Cursor aus select, order by count(Spalte2-Werte)
    – Loop
    — Werte noch nicht vorhanden?
    ---- Werte in Array einfügen
    – End Loop

Nun hätte ich ein Array, das alle Spalte1-Werte enthält, deren Spalte2-Werte-Kombinationen eindeutig sind.

Ein Loop durch dieses Array incl. select aller passenden Spalte2-Werte erzeugt ein endgültiges Array, welches ich dann zurückgeben kann.

Nur… wie stelle ich das mit den Arrays an? Oder ist der Ansatz total falsch?

Habe ich alle Fragen beantwortet oder nun auch die restlichen Klarheiten beseitigt? :wink:

Gruß
Karsten

Hallo Karsten,

wenn Dich nicht interssiert, ob Vater oder Mutter wann das Bad besucht haben, dürfte es dir doch auch egal sein, wenn staatdessen es Sohn und Tochter besucht haben, oder liege ich da falsch? Dann würdest Du eigentlich die Frage klären wollen, wieviele Personen maximal bei einem Besuch auf einer Karte „registiert“ wurden. Irgendwie fehlt aber dann bei Deinem Beispiel ein Zeitstempel oder Du erhälst bei jedem Besuch eine andere Nummer, auch wenn die gleiche Karte verwendet wird.

MfG Georg V.

SOLVED: Wertekombination nur einmalig anzeigen
Vielen Dank an alle, die sich mit diesem Problem beschäftigt und Lösungsansätze gesucht haben.

Die Lösung brachte mir letztlich eine Collection mit „Indexed_by VARCHAR2“ innerhalb einer Table-Function.

Grüße