1.8k Aufrufe
Gefragt in Datenbanken von vanwaal Einsteiger_in (3 Punkte)
Bitte helft mir!!!

Meine Access (2007) Datenbank besteht aus 3 Spalten:
In Spalte A steht ein Text, in Spalte B und C jeweils eine zweistellige Dezimalzahl (Double; 3 Nachkommastellen).

Nun möchte ich, dass die Duplikate gefunden werden.

Als Duplikat sollen aber nur jene Zeilen gelten, deren Einträge in Spalte A exakt übereinstimmen, und deren Dezimalzahlen in Spalte B und Spalte C um maximal ±0,03 bzw. ±0,05 voneinander (in der selben Spalte) abweichen.

Anschließend soll in Spalte A nur mehr ein Eintrag des Duplikates und in den Spalten B und C jeweils der Mittelwert der Duplikate ausgegeben werden.

gegeben:
SpalteA | SpalteB | SpalteC
heute | 0,043 | -1,587
morgen | 24,983 | 4,456
morgen | 26,234 | 4,456
heute | 0,019 | -1,537

gewünschtes Ergebnis:
SpalteA | SpalteB | SpalteC
heute | 0,031 | -1,562

Hat jemand von euch eine Lösung?

Danke.

5 Antworten

0 Punkte
Beantwortet von saarbauer Profi (15.6k Punkte)
Hallo,

kommt wohl keiner richig mit klar, da u.a. dein gewünschtes Ergebnis in den gegebenen Werten nicht auftaucht und somit kaum Zusammenhänge herzustellen sind.

Gruß

Helmut
0 Punkte
Beantwortet von rahi Experte (1.4k Punkte)
Hallo Helmut,

ich muss dir Recht geben, die Angaben sind dürftig, aber nicht zu dürftig. Das Ergebnis zeigt, dass von den gefunden Zeilen, die Mittelwerte ausgegeben werden müssen. Vanwaal korrigiere mich, wenn ich falsch liege.

Hier ein Ansatz:

Die Tabelle Tabelle2 enthält die 3 Felder entsprechend der oben gemachten angaben. Dann erstelle zu nächst eine Abfrage "Abfrage1" mit dem SQL-Statement:

SELECT Tabelle2.SpalteA, Avg(Tabelle2.SpalteB) AS MittelwertvonSpalteB, Avg(Tabelle2.SpalteC) AS MittelwertvonSpalteC
FROM Tabelle2
GROUP BY Tabelle2.SpalteA;


Danach eine Abfrage "Abfrage2" mit den SQL-Statement:

SELECT Abfrage1.SpalteA, Abfrage1.MittelwertvonSpalteB, Abfrage1.MittelwertvonSpalteC
FROM Abfrage1 INNER JOIN Tabelle2 ON Abfrage1.SpalteA = Tabelle2.SpalteA
WHERE (((Abs([MittelwertvonSpalteB]-[spalteB])<=0.03)=True) AND ((Abs([MittelwertvonSpalteC]-[SpalteC])<=0.05)=True))
GROUP BY Abfrage1.SpalteA, Abfrage1.MittelwertvonSpalteB, Abfrage1.MittelwertvonSpalteC;


Das Ergebis lautet:

SpalteA MittelwertvonSpalteB MittelwertvonSpalteC
heute 0,031 -1,562

Passt das?

Gruß
Ralf
0 Punkte
Beantwortet von rahi Experte (1.4k Punkte)
Hallo Helmut,

der Ansatz war etwas zu kurz gedacht. Erstens müssten die Zahlenwerte in der Abfrage halbiert (0,015 und 0,025) werden und zweitens wird das ganze nicht funktionieren, wenn mehr als zwei Werte für den Mittelwert herangezogen werden würden. Da würde ich mich jetzt Saarbauer anschließen und dich bitten das Problem zu konkretisieren.

Gruß
Ralf
0 Punkte
Beantwortet von asok Einsteiger_in (37 Punkte)
Bei der Aufgabenstellung gibt es ein konzeptionelles Problem:


deren Dezimalzahlen in Spalte B und Spalte C um maximal ±0,03 bzw. ±0,05 voneinander (in der selben Spalte) abweichen.


Beispiel:


X | A
---------
1 | 0.100
2 | 0.105
3 | 0.110


1 und 2 sind nach der Definition oben identisch, ebenso 2 und 3. Und wenn 1 = 2 und 2 = 3, dann erwarte ich, dass 1 = 3. Das ist aber nicht der Fall, da die Differenz von 1 und 3 größer als .005 ist.

Etwas theoretischer gesprochen: Das, was in der Aufgabe als "Gleichheit" angenommen wird, ist tatsächlich kein äquivalenter Zusammenhang (da es nicht transitiv ist). Ich kann mir nicht denken, dass man so irgendwelche Gruppen bilden kann, sei es mit SQL oder sonstwie.

Hier muss eindeutig erstmal klar definiert werden, was wovon wie abweichen soll.
0 Punkte
Beantwortet von lorf55 Mitglied (699 Punkte)
Hallo Loitz,
wenn theoretisch feststeht, dass es nicht funktionieren kann, kann ich ja auch noch meinen Senf dazu geben.
Ich habe mich mal an RaHis Ansatz orientiert und benutze auch 2 Abfragen für meine Lösung.
Abfrage1: Rechnet wie bei RaHi die Durchschnittswerte aus, allerdings hier die der Duplikate:
SELECT T1.A AS SpalteA,
(SELECT avg(T.B) FROM T1 as T
WHERE (T.B between (T1.B-0.03) and (T1.B+0.03)) and (T.C between (T1.C-0.05) and (T1.C+0.05)) ) AS SpalteB,
(SELECT avg(T.C) FROM T1 as T
WHERE (T.C between (T1.C-0.05) and (T1.C+0.05)) and (T.B between (T1.B-0.03) and (T1.B+0.03)) ) AS SpalteC
FROM T1;

Diese WHERE-Klauseln sehen etwas belastend aus, sind aber nötig. Damit gibts eine Tabelle, die die Durchschnittswerte
und die Nicht-Durchschnittswerte enthält.
Um nur die Durchschnittswerte rauszufiltern, habe ich die Abfrage2:
SELECT DISTINCT *
FROM TestABC AS ABC
WHERE (SELECT count(*)
FROM TestABC as T
WHERE (T.SpalteA=ABC.SpalteA) and (T.SpalteB=ABC.SpalteB) and (T.SpalteC=ABC.SpalteC))
>=2;
Damit erhalte ich auch für die Tabelle:
A B C
heute 0,043 -1,587
morgen 24,983 4,456
morgen 26,234 4,456
heute 0,019 -1,537
heute 0,031 -1,545
gestern 0,067 3,445
gestern 0,057 3,435
gestern 0,062 3,439

Die Lösung:
SpalteA SpalteB SpalteC
gestern 0,062 3,43966666666667
heute 0,031 -1,55633333333333

Ist sicher keine sonderlich performante Lösung, aber sicher besser als mit Hand rausgesucht.
Wenn sie überhaupt wirklich richtig ist. So ganz sicher bin ich mir da nicht.

Gruß
lorf
...