1Danke
ERLEDIGT
NEIN
NEIN
ANTWORTEN
2
2
ZUGRIFFE
1229
1229
EMPFEHLEN
-
Halli Hallo!
Ich habe folgende Tabelle fiktiv ausgedacht ( es sind viel mehr als 250000 Datensätze )
ID+++++ART++++++GUELTIG_AB+++++++DATUM_TS+++++++ERGEBNIS
100 ++++ IQ TEST+++++01.01.1901++++++1101201017562445++++++10
100 ++++ SEHTEST+++++25.12.2009++++++2512200916362255++++++2-
100 ++++ IQ TEST+++++11.02.2010++++++1102201016443317++++++13
Ein kurze Erläuterung zu der Tabelle:
Ich kann an der ganzen Datenbank NICHTS verändern! Nur abfragen!
Es sind noch andere Felder vorhanden, welche hierfür aber keine Rolle spielen.
Die Spalte DATUM_TS ist im TIMESTAMP Format. Die Spalte ID ebenso.
Die Spalte ID dient als Verknüpfung zu einer Personentabelle.
Die Spalte ERGEBNIS ist CHAR(4).
In der Spalte GUELTIG_AB steht das Datum ab wann der Wert der Spalte ERGEBNIS gültig ist. Die Datumswerte von abgelaufenen Tests werden dann einfach mit "01.01.1901" aufgefüllt.
Nun mein Problem:
Ich möchte alle Personen abfragen welche beim letzten Sehtest einen Wert zwischen 10 und 15 hatten UND sich dieser Wert verschlechtert hat.
Beispiel: Eine Person hatte erst 10 Punkte und jetzt 13. Dann soll diese Person in der Liste erscheinen.
Eine Person hatte erst 11 Punkte und 16. Dann soll diese Person ebenfalls erscheinen.
Welchen Daten sollen ausgegeben werden?
- Daten aus der Personentabelle
- Datum des letzten Tests
- Testart
- Ergebnis des Testes
Ich habe schon einiges probiert (Nested Table, Subselect) doch komme ich nicht hin. Leider kann ich hier auch nichts an SQL einbinden, da der PC nicht am Internet ist.
Ich danke schon mal im Voraus!Geändert von mirscho (11.03.10 um 16:53 Uhr)
-
Ich habe hier eine Lösungsmöglichkeit für dich ausgeknobelt; ich hoffe, die Parameter in der WHERE-Klausel entsprechen deinen Wünschen. Notfalls kannst du sie aber leicht anpassen, denn eigentlich ist die Abfrage nicht schwer zu verstehen. Grundlage ist ein Equi-Join der Tabelle test mit sich selbst, um so die Werte der Spalte ergebnis zweimal zur Verfügung zu haben.
Die Abfrage setzt voraus, dass für eine Person nur maximal zwei Datensätze mit Gültigkeitsdatum > 01.01.1901 vorhanden sind, sonst sind die Resultate nicht eindeutig.
Obwohl die Vorgehensweise im Prinzip funktionieren dürfte, rate ich aus Performancegründen davon ab. Ich persönlich würde lieber einen passenden Datenbankauszug in eine Textdatei erstellen und diese mit einem Programm oder awk-Skript auswerten; das dürfte wahrscheinlich schneller und sicherer sein als ein Equi-Join über 250.000 Datensätze.Code sql:1 2 3 4 5 6 7 8 9 10 11 12
SELECT p1.*, t1.datum_ts, t1.art, t1.ergebnis, t2.ergebnis FROM test t1, test t2, person p1 WHERE p1.id = t1.id AND t1.id = t2.id AND t1.art = t2.art AND t1.art = "Sehtest" AND t1.gueltig_ab > 01.01.1901 AND t2.gueltig_ab > 01.01.1901 AND t1.datum_ts > t2.datum_ts AND t2.ergebnis >= 10 AND t2.ergebnis <= 16 AND t1.ergebnis > t2.ergebnis
ACHTUNG: Anwendung auf eigene Gefahr. Der Autor übernimmt keine Haftung für z.B. Rechnerabstürze wegen Speichermangels oder Prozessorüberlastung.Vielen Dank für die Nutzung des Bewerten- und Danke-Buttons
Wenn man sieht, dass man einen anderen glücklich gemacht hat, ist die Welt um zwei glückliche Menschen reicher.
-
19.03.10 18:43 #3
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
interessante Fragestellung
Habs gerade mal nachgespielt.
Wenn db2 die von Oracle bekannten analytischen Funktionen lead / lag kennen würde
könnte man das Problem damit recht einfach lösen.
Leider gibt es diese Funktionen so nicht direkt in DB2 aber man kann sich die
Funktionalität auch selber bauen, in dem man eine Aggregatsfunktion mit entsprechender
over / partition-Klause verwendet.
Zur Lösung habe ich mit max(xxx) over (partition by ...) gearbeitet und somit die Oracle-Funktion lag
emuliert.
Unsere Tabelle test_records:
Code sql:1 2 3 4 5 6 7 8 9 10 11 12 13 14
CREATE TABLE "DB2ADMIN"."TEST_RECORDS" ( "ID" BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY ( START WITH +0 INCREMENT BY +1 MINVALUE +0 MAXVALUE +9223372036854775807 NO CYCLE NO CACHE NO ORDER ) , "USERID" BIGINT NOT NULL , "KIND" VARCHAR(32) NOT NULL , "VALID_FROM" BIGINT NOT NULL , "SCORE" BIGINT NOT NULL ) IN "USERSPACE1" ;
Unsere Inserts:
Code sql:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (1,'sehtest',20010101,12); INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (1,'sehtest',20010103,15); -- Verschlechterung INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (1,'sehtest',20010110,13); -- Nur 1 Satz -> Keine Verschlechterung INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (2,'sehtest',20010101,6); INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (3,'sehtest',20010101,7); INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (3,'sehtest',20010102,10); -- Verschlechterung INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (3,'sehtest',20010103,9); INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (4,'sehtest',20010101,3); INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (4,'sehtest',20010102,5); INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (4,'sehtest',20010103,2); -- Verbesserung INSERT INTO DB2ADMIN."TEST_RECORDS" (userid,kind,valid_from,score) VALUES (4,'sehtest',20010104,11);
Daten:
Code :1 2 3 4 5 6 7 8 9 10 11 12
ID;USERID;KIND;VALID_FROM;SCORE 26;1;"sehtest";20010101;12 27;1;"sehtest";20010103;15 28;1;"sehtest";20010110;13 29;2;"sehtest";20010101;6 30;3;"sehtest";20010101;7 31;3;"sehtest";20010102;10 32;3;"sehtest";20010103;9 33;4;"sehtest";20010101;3 34;4;"sehtest";20010102;5 35;4;"sehtest";20010103;2 36;4;"sehtest";20010104;11
Code sql:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
SELECT t.id ,t.userid ,t.kind ,t.valid_from ,t.current_score ,t.previous_score FROM ( SELECT id , userid , kind , valid_from , score current_score , MAX(score) OVER (partition BY userid ORDER BY valid_from ASC ROWS BETWEEN 1 preceding AND 1 preceding) previous_score , MAX(valid_from) OVER (partition BY userid) latest_valid_from FROM DB2ADMIN."TEST_RECORDS" ) t WHERE t.current_score < t.previous_score AND t.valid_from = t.latest_valid_from ORDER BY t.userid , t.valid_from
Ausgabe:
User 2 ist nicht dabei da es dafür nur einen Eintrag gibt -> keine VerschlechterungCode :1 2 3
ID;USERID;KIND;VALID_FROM;CURRENT_SCORE;PREVIOUS_SCORE 28;1;"sehtest";20010110;13;15 32;3;"sehtest";20010103;9;10
User 4 hat beim letzten Test eine Verbesserung geschafft.
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
Ähnliche Themen
-
Aus einer SQL Tabelle mehrere verschiedene Werte einer Spalte auslesen
Von supercat1510 im Forum PHPAntworten: 5Letzter Beitrag: 02.06.10, 12:52 -
Automatisch Tabelle mit dem namen einer Spalte einer anderen Tabelle erstellen
Von Chris-P im Forum PHPAntworten: 11Letzter Beitrag: 26.06.08, 19:49 -
mehrere Werte in eine Spalte
Von maxikey im Forum PHPAntworten: 5Letzter Beitrag: 11.05.08, 21:08 -
Unterschiedliche Werte gleichzeitig in MySQL-Tabelle schreiben
Von qsrs im Forum PHPAntworten: 6Letzter Beitrag: 04.06.05, 17:15 -
Werte einer Tabelle durch Werte anderer Tabelle ersetzen
Von Oremliac im Forum Relationale DatenbanksystemeAntworten: 1Letzter Beitrag: 28.01.04, 21:21





Zitieren

Login





