# SQL-Statement gesucht die 2.



## The_S (25. Aug 2006)

Hi,

ich suche mal wieder ein SQL Statement. Und zwar habe ich folgende Tabellenstruktur:

Kursveranstaltung:

```
Datum		KVID

20060801	1
20060720	2
20060710	3
20060701	4
```

Besuchte_Kursveranstaltung:

```
EID		KVID

1		  1
1		  2
2		  2
1		  3
2		  3
1		  4
```

Kursveranstaltung wird u. a. ein Datum (INT) und eine Dazugehörige ID gespeichert (und sonst noch andere Sachen, welche hier aber nicht relevant sind). In Besuchte_Kursveranstaltungen wird erfasst welches Elternteil (EID) an welcher Kursveranstaltung (KVID) teilgenommen hat.

Ich benötige jetzt ein SQL-Statement, welches mir ein ResultSet mit allen Datensätze der Tabelle Elternteil zurückgibt, deren letzter Kursbesuch vor einem bestimmten Datum liegt. Als Beispiel mal der 31.07.2006. Mit den Daten von oben, sollte ich also den Datensatz von der EID 1 zurückbekommen.

Das habe ich mit folgenden Statement versucht


*SELECT * FROM Elternteil WHERE EID IN 
(SELECT EID AS old FROM Besuchte_Kursveranstaltung WHERE KVID IN 
(SELECT KVID FROM Kursveranstaltung WHERE 20063107 > 
(SELECT MAX(Datum) FROM Kursveranstaltung WHERE KVID IN 
(SELECT KVID From Besuchte_Kursveranstaltung WHERE EID = old))))
*

was aber nicht funktioniert, da er die Spalte old im letzten Subselect nicht kennt. Momentan sehe ich zwei Lösungsansätze, für die ich aber eure Hilfe bräuchte 

*a) Wie kann ich in einem Subselect auf einen Wert eines "übergeordnetem" Selects zugreifen?*

*b) Sehe ich den Wald vor lauter Bäumen nicht und es geht anders und/oder einfacher!?*

[edit] irgendwie glaub ich, dass mein Ansatz komplett falsch ist :cry:


----------



## DP (26. Aug 2006)

```
select * from Kursveranstaltung, Besuchte_Kursveranstaltung where Kursveranstaltung.KVID = Besuchte_Kursveranstaltung.KVID and datum < x
```

?!


----------



## André Uhres (26. Aug 2006)

Der Vorschlag von DP ist sehr gut. Im speziellen Fall könnte er so angewandt werden:

select * from Elternteil where eid in (select eid from Kursveranstaltung, Besuchte_Kursveranstaltung 
where Kursveranstaltung.KVID = Besuchte_Kursveranstaltung.KVID and datum > 20060731 )


----------



## The_S (26. Aug 2006)

Ah, Joins ... damit konnte ich mich noch nie anfreunden  . Ich werds gleich mal ausprobieren 

[edit] Funktioniert noch nicht ganz. Ich möchte variabel überprüfen, ob alle Elternteile ihren letzten Kursbesuch vor, nach oder am 31.07.2006 hatten. Deshalb muss ich noch irgendwie das MAX(Datum) gruppiert nach Elternteil berücksichtigen. Was auch letztendlich der Grund war, weshalb ich mit meinen Subselect am Ende war


----------



## DP (26. Aug 2006)

wieso machste das nicht beim durchlaufen des resultsets?!


----------



## The_S (26. Aug 2006)

Sollte man nicht so viele "Ausgrenzungen" wie möglich von der DB erledigen lassen? Und imho müsste das ja auch irgendwie gehen!?


----------



## The_S (8. Sep 2006)

*push*

Mittlerweile bin ich hier am verzweifeln. Ich bekomme das Statement einfach nicht auf die Reihe (brauch das auch noch für drei andere Statements) und am Montag ist abgabe ...  :cry:


----------



## The_S (9. Sep 2006)

Bin dank Hilfe eines Dritten auf folgende Lösung gekommen

SELECT EID FROM (SELECT temp.EID, MAX(temp.Datum) FROM (SELECT EID, Datum FROM besuchte_kursveranstaltung INNER JOIN kursveranstaltung ON besuchte_kursveranstaltung.KVID = kursveranstaltung.KVID ORDER BY kursveranstaltung.DATUM DESC) as temp GROUP BY temp.EID HAVING MAX(temp.DATUM) < 20061103))


----------



## DP (9. Sep 2006)

und wo bekommt du heraus



			
				Hobbit_Im_Blutrausch hat gesagt.:
			
		

> ob alle Elternteile ihren letzten Kursbesuch vor, nach oder am 31.07.2006 hatten



?


----------



## The_S (9. Sep 2006)

DP hat gesagt.:
			
		

> und wo bekommt du heraus
> 
> 
> 
> ...



War nur ein Beispiel-Datum. Im Statment ist das Datum halt der 3.11.2006. Ging mir jetzt mehr um das generelle, als um dieses eine spezielle Datum


----------



## DP (9. Sep 2006)

das ist klar. aber woran siehst du ob der kurs vor, nach oder am tag x war?


----------



## The_S (9. Sep 2006)

SELECT EID FROM (SELECT temp.EID, MAX(temp.Datum) FROM (SELECT EID, Datum FROM besuchte_kursveranstaltung INNER JOIN kursveranstaltung ON besuchte_kursveranstaltung.KVID = kursveranstaltung.KVID ORDER BY kursveranstaltung.DATUM DESC) as temp GROUP BY temp.EID HAVING MAX(temp.DATUM) *<* 20061103))

am >/</= Zeichen


----------



## DP (9. Sep 2006)

brüllwitz! ich dachte das soll ein stmt erledigen!

dann lieber die im speicher-durchlauf-variante


----------



## The_S (9. Sep 2006)

hm?


----------



## DP (9. Sep 2006)

*schläfenmassier*

für dein ergebnis brauchst du


```
SELECT EID FROM (SELECT temp.EID, MAX(temp.Datum) FROM (SELECT EID, Datum FROM besuchte_kursveranstaltung INNER JOIN kursveranstaltung ON besuchte_kursveranstaltung.KVID = kursveranstaltung.KVID ORDER BY kursveranstaltung.DATUM DESC) as temp GROUP BY temp.EID HAVING MAX(temp.DATUM) < 20061103));
SELECT EID FROM (SELECT temp.EID, MAX(temp.Datum) FROM (SELECT EID, Datum FROM besuchte_kursveranstaltung INNER JOIN kursveranstaltung ON besuchte_kursveranstaltung.KVID = kursveranstaltung.KVID ORDER BY kursveranstaltung.DATUM DESC) as temp GROUP BY temp.EID HAVING MAX(temp.DATUM) > 20061103));
SELECT EID FROM (SELECT temp.EID, MAX(temp.Datum) FROM (SELECT EID, Datum FROM besuchte_kursveranstaltung INNER JOIN kursveranstaltung ON besuchte_kursveranstaltung.KVID = kursveranstaltung.KVID ORDER BY kursveranstaltung.DATUM DESC) as temp GROUP BY temp.EID HAVING MAX(temp.DATUM) = 20061103));
```

also 3 abfragen, oder?!


----------



## The_S (9. Sep 2006)

Kommt darauf an wie mans sieht  . Da ich vor, nach *oder* am geschrieben habe brauche ich immer nur eines. Sprich ich hab das Statement, bei dem ich einfach immer nur das Datum und den Operator austausche. Im Prinzip also 3 Abfragen, von denen aber immer nur jeweils eine benötigt wird (jenachdem was der User möchte  ).


----------

